summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSamy Pessé <samypesse@gmail.com>2016-02-11 10:07:15 +0100
committerSamy Pessé <samypesse@gmail.com>2016-02-11 10:07:15 +0100
commit52c4dc49cf460dad4edc42457ba9e3ca4c7674d5 (patch)
tree6d5d123756c8d79ab5add4660e7b66beb3e89736 /lib
parent44ad70320a0d0b907702c57e560c6a60373c9bca (diff)
downloadgitbook-52c4dc49cf460dad4edc42457ba9e3ca4c7674d5.zip
gitbook-52c4dc49cf460dad4edc42457ba9e3ca4c7674d5.tar.gz
gitbook-52c4dc49cf460dad4edc42457ba9e3ca4c7674d5.tar.bz2
Normalize errors
Diffstat (limited to 'lib')
-rw-r--r--lib/backbone/summary.js5
-rw-r--r--lib/book.js18
-rw-r--r--lib/output.js3
-rw-r--r--lib/utils/error.js53
-rw-r--r--lib/utils/path.js11
5 files changed, 74 insertions, 16 deletions
diff --git a/lib/backbone/summary.js b/lib/backbone/summary.js
index 009fb76..35f65e6 100644
--- a/lib/backbone/summary.js
+++ b/lib/backbone/summary.js
@@ -3,6 +3,7 @@ var util = require('util');
var url = require('url');
var location = require('../utils/location');
+var error = require('../utils/error');
var BackboneFile = require('./file');
@@ -15,10 +16,10 @@ function TOCArticle(summary, title, ref, articles, parent) {
this.title = title;
if (ref && location.isExternal(ref)) {
- throw new Error('SUMMARY can only contains relative locations');
+ throw error.ParsingError(new Error('SUMMARY can only contains relative locations'));
}
if (!title) {
- throw new Error('SUMMARY entries should have an non-empty title');
+ throw error.ParsingError(new Error('SUMMARY entries should have an non-empty title'));
}
var parts = url.parse(ref);
diff --git a/lib/book.js b/lib/book.js
index fd20a94..def724b 100644
--- a/lib/book.js
+++ b/lib/book.js
@@ -11,6 +11,7 @@ var Summary = require('./backbone/summary');
var Langs = require('./backbone/langs');
var Page = require('./backbone/page');
var pathUtil = require('./utils/path');
+var error = require('./utils/error');
var Promise = require('./utils/promise');
@@ -40,7 +41,7 @@ function Book(opts) {
logLevel: 'info'
});
- if (!opts.fs) throw new Error('Book requires a fs instance');
+ if (!opts.fs) throw error.ParsingError(new Error('Book requires a fs instance'));
// Root path for the book
this.root = opts.root;
@@ -101,9 +102,10 @@ Book.prototype.prepareConfig = function() {
Book.prototype.resolve = function() {
var filename = path.resolve.apply(path, [this.root].concat(_.toArray(arguments)));
if (!this.isFileInScope(filename)) {
- var err = new Error('EACCESS: "' + filename + '" not in "' + this.root + '"');
- err.code = 'EACCESS';
- throw err;
+ throw error.FileOutOfScopeError({
+ filename: filename,
+ root: this.root
+ });
}
return filename;
@@ -154,7 +156,7 @@ Book.prototype.parse = function() {
.then(function() {
if (that.isMultilingual()) {
if (that.isLanguageBook()) {
- throw new Error('A multilingual book as a language book is forbidden');
+ throw error.ParsingError(new Error('A multilingual book as a language book is forbidden'));
}
that.log.info.ln('Parsing multilingual book, with', that.langs.count(), 'languages');
@@ -180,14 +182,14 @@ Book.prototype.parse = function() {
.then(function() {
if (that.readme.exists()) return;
- throw new Error('No README file (or is ignored)');
+ throw new error.FileNotFoundError({ filename: 'README' });
})
// Parse the summary
.then(that.summary.load)
.then(function() {
if (!that.summary.exists()) {
- throw new Error('No SUMMARY file (or is ignored)');
+ throw new error.FileNotFoundError({ filename: 'SUMMARY' });
}
// Index summary's articles
@@ -229,7 +231,7 @@ Book.prototype.isFileIgnored = function(filename) {
// Read a file in the book, throw error if ignored
Book.prototype.readFile = function(filename) {
- if (this.isFileIgnored(filename)) return Promise.reject(new Error('File "'+filename+'" is ignored'));
+ if (this.isFileIgnored(filename)) return Promise.reject(new error.FileNotFoundError({ filename: filename }));
return this.fs.readAsString(this.resolve(filename));
};
diff --git a/lib/output.js b/lib/output.js
index 2fb3938..5c28ca1 100644
--- a/lib/output.js
+++ b/lib/output.js
@@ -6,11 +6,12 @@ var path = require('path');
var Promise = require('./utils/promise');
var pathUtil = require('./utils/path');
+var error = require('./utils/error');
var generators = require('./generators');
var PluginsManager = require('./plugins');
function Output(book, type) {
- if (!generators[type]) throw new Error('Generator not found"' + type + '"');
+ if (!generators[type]) throw error.GeneratorNotFoundError({ generator: type });
this.book = book;
this.log = this.book.log;
diff --git a/lib/utils/error.js b/lib/utils/error.js
index 66e20db..4ccf83d 100644
--- a/lib/utils/error.js
+++ b/lib/utils/error.js
@@ -1,4 +1,6 @@
var _ = require('lodash');
+var TypedError = require('error/typed');
+var WrappedError = require('error/wrapped');
// Enforce as an Error object, and cleanup message
function enforce(err) {
@@ -8,6 +10,55 @@ function enforce(err) {
return err;
}
+// Random error wrappers during parsing/generation
+var ParsingError = WrappedError({
+ message: 'Parsing Error: {origMessage}',
+ type: 'server.parsing-failed'
+});
+var GenerationError = WrappedError({
+ message: 'Generation Error: {origMessage}',
+ type: 'server.parsing-failed'
+});
+
+// Error when output generator does not exists
+var GeneratorNotFoundError = TypedError({
+ type: 'server.404',
+ message: 'Generator "{generator}" does not exists',
+ generator: null
+});
+
+// A file does not exists
+var FileNotFoundError = TypedError({
+ type: 'server.404',
+ message: 'No "{filename}" file (or is ignored)',
+ filename: null
+});
+
+// A file is outside the scope
+var FileOutOfScopeError = TypedError({
+ type: 'server.404',
+ message: '"{filename}" not in "{root}"',
+ filename: null,
+ root: null,
+ code: 'EACCESS'
+});
+
+// Error for nunjucks templates
+var TemplateError = WrappedError({
+ message: 'Error compiling template "{filename}": {origMessage}',
+ type: 'client.template-failed',
+ filename: null
+});
+
module.exports = {
- enforce: enforce
+ enforce: enforce,
+
+ ParsingError: ParsingError,
+ GenerationError: GenerationError,
+
+ FileNotFoundError: FileNotFoundError,
+ FileOutOfScopeError: FileOutOfScopeError,
+
+ GeneratorNotFoundError: GeneratorNotFoundError,
+ TemplateError: TemplateError
};
diff --git a/lib/utils/path.js b/lib/utils/path.js
index 2d722a5..f195d6c 100644
--- a/lib/utils/path.js
+++ b/lib/utils/path.js
@@ -1,6 +1,8 @@
var _ = require('lodash');
var path = require('path');
+var error = require('./error');
+
// Normalize a filename
function normalizePath(filename) {
return path.normalize(filename);
@@ -15,7 +17,7 @@ function isInRoot(root, filename) {
// Resolve paths in a specific folder
// Throw error if file is outside this folder
function resolveInRoot(root) {
- var input, result, err;
+ var input, result;
input = _.chain(arguments)
.toArray()
@@ -31,9 +33,10 @@ function resolveInRoot(root) {
result = path.resolve(root, input);
if (!isInRoot(root, result)) {
- err = new Error('EACCESS: "' + result + '" not in "' + root + '"');
- err.code = 'EACCESS';
- throw err;
+ throw new error.FileOutOfScopeError({
+ filename: result,
+ root: root
+ });
}
return result;