diff --git a/examples/01-basic/routes.js b/examples/01-basic/routes.js
index 39905a2..cfba368 100644
--- a/examples/01-basic/routes.js
+++ b/examples/01-basic/routes.js
@@ -2,6 +2,14 @@ const path = require('path')
module.exports = {
router: [
+ {
+ type: 'ROUTE',
+ method: ['GET'],
+ path: '/error-page',
+ callback: (req, res) => {
+ throw new Error('Simulate 500')
+ }
+ },
{
type: 'ROUTE',
method: ['GET'],
diff --git a/src/assets/default_pages/4xx.html b/src/assets/default_pages/4xx.html
new file mode 100644
index 0000000..2560154
--- /dev/null
+++ b/src/assets/default_pages/4xx.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+ 404
+
+
The page could not be found
+
+
+
+
diff --git a/src/assets/default_pages/5xx.html b/src/assets/default_pages/5xx.html
new file mode 100644
index 0000000..2fb16a0
--- /dev/null
+++ b/src/assets/default_pages/5xx.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+ 500
+
+
The page could not be found
+
+
+
+
diff --git a/src/cherry.js b/src/cherry.js
index abfc161..48e8906 100644
--- a/src/cherry.js
+++ b/src/cherry.js
@@ -4,6 +4,7 @@ const HookConfigurator = require('./configuration/HookConfigurator')
const MiddlewareConfigurator = require('./configuration/MiddlewareConfigurator')
const RouteConfigurator = require('./configuration/RouteConfigurator')
const RedirectionConfigurator = require('./configuration/RedirectionConfigurator')
+const DefaultErrorPageConfigurator = require('./configuration/DefaultErrorPageConfigurator')
const ORMManager = require('./orm/ORMManager')
const CherryServerManager = require('./server/CherryServerManager')
@@ -16,6 +17,7 @@ class Cherry {
this.middlewareConfigurator = new MiddlewareConfigurator()
this.routeConfigurator = new RouteConfigurator()
this.redirectionConfigurator = new RedirectionConfigurator()
+ this.defaultErrorPageConfigurator = new DefaultErrorPageConfigurator()
this.ormManager = new ORMManager(this)
this.cherryServerManager = new CherryServerManager(this)
@@ -26,15 +28,12 @@ class Cherry {
* @param {Object} options The options to configure Cherry
*/
configure (options = {}) {
- // if (check.isDefined(options, 'onError')) {
- // this.dispatcher.onError(options.onError)
- // }
-
this.pluginConfigurator.configure(options)
this.hookConfigurator.configure(options)
this.middlewareConfigurator.configure(options)
this.routeConfigurator.configure(options)
this.redirectionConfigurator.configure(options)
+ this.defaultErrorPageConfigurator.configure(options)
if (this.pluginConfigurator.getPlugin('DatabaseEngine') && typeof options.database !== 'undefined') {
this.ormManager.setPlugin(this.pluginConfigurator.getPlugin('DatabaseEngine'))
diff --git a/src/configuration/DefaultErrorPageConfigurator.js b/src/configuration/DefaultErrorPageConfigurator.js
new file mode 100644
index 0000000..3f5c1d0
--- /dev/null
+++ b/src/configuration/DefaultErrorPageConfigurator.js
@@ -0,0 +1,51 @@
+const path = require('path')
+const CherryConfigurator = require('../abstract/CherryConfigurator')
+const check = require('../helpers/check')
+
+/**
+ * The configurator of the default error pages
+ * Inherits from the abstract CherryConfigurator
+ */
+class DefaultErrorPageConfigurator extends CherryConfigurator {
+ constructor () {
+ super({})
+
+ this.manager.clientErrorPage = this.clientErrorPage
+ this.manager.serverErrorPage = this.serverErrorPage
+ }
+
+ /**
+ * Configure the default pages process in case of error
+ * @param {Object} options The options set to the cherry instance
+ */
+ configure (options) {
+ if (check.isDefined(options, 'defaultPages')) {
+ Object.keys(this.manager).forEach((defaultPage) => {
+ if (check.isDefined(options.defaultPages, defaultPage)) {
+ this.manager[defaultPage] = options.defaultPages[defaultPage]
+ }
+ })
+ }
+ }
+
+ /**
+ * The default process in case of a 4xx page
+ * @param {CherryIncomingMessage} req The current request
+ * @param {CherryServerResponse} res The response object
+ */
+ clientErrorPage (req, res) {
+ res.html(path.join(__dirname, '../assets/default_pages/4xx.html'), { statusCode: 404 })
+ }
+
+ /**
+ * The default process in case of a 5xx page
+ * @param {CherryIncomingMessage} req The current request
+ * @param {CherryServerResponse} res The response object
+ * @param {Error} err The error catch
+ */
+ serverErrorPage (req, res, err) {
+ res.html(path.join(__dirname, '../assets/default_pages/5xx.html'), { statusCode: 500 })
+ }
+}
+
+module.exports = DefaultErrorPageConfigurator
diff --git a/src/processor/Dispatcher.js b/src/processor/Dispatcher.js
index 13427e0..f673449 100644
--- a/src/processor/Dispatcher.js
+++ b/src/processor/Dispatcher.js
@@ -38,8 +38,7 @@ class Dispatcher {
this.executeRoute(matchingRouteResponse, request, response)
}
} else {
- response.writeHead(404)
- response.end('')
+ this.cherry.defaultErrorPageConfigurator.manager.clientErrorPage(request, response)
}
}
@@ -78,10 +77,7 @@ class Dispatcher {
request._route = matchingRouteResponse.getMatchingRoute()
this.resolver.resolve(request, response)
}).catch((err) => {
- // @todo : manage error
- console.log(err)
- response.writeHead(500)
- response.end('')
+ this.cherry.defaultErrorPageConfigurator.manager.serverErrorPage(request, response, err)
})
}
}
diff --git a/src/processor/Resolver.js b/src/processor/Resolver.js
index b973522..87d52a8 100644
--- a/src/processor/Resolver.js
+++ b/src/processor/Resolver.js
@@ -46,12 +46,9 @@ class Resolver {
{ request, response, processResult: asyncResult },
asyncResult
)
- }).catch((e) => {
- // @todo use the onError method
- console.log('Error in _resolve', e)
+ }).catch((error) => {
if (!response.finished) {
- response.writeHead(500, { 'Content-Type': 'application/json' })
- response.end(JSON.stringify(e))
+ this.cherry.defaultErrorPageConfigurator.manager.serverErrorPage(request, response, error)
}
})
} else {
diff --git a/test/specs/configuration/DefaultErrorPageConfigurator.spec.js b/test/specs/configuration/DefaultErrorPageConfigurator.spec.js
new file mode 100644
index 0000000..e7a0014
--- /dev/null
+++ b/test/specs/configuration/DefaultErrorPageConfigurator.spec.js
@@ -0,0 +1,39 @@
+const DefaultErrorPageConfigurator = require(path.join(__root, './src/configuration/DefaultErrorPageConfigurator'))
+
+const default404 = () => {
+ return 404
+}
+let defaultErrorPageConfigurator = null
+let customDefaultErrorPageConfigurator = null
+const fakeResponse = {
+ errorCode: 0,
+ html: function (path, options) {
+ this.errorCode = options.statusCode
+ }
+}
+
+describe('DefaultErrorPageConfigurator', () => {
+ before(() => {
+ defaultErrorPageConfigurator = new DefaultErrorPageConfigurator()
+ customDefaultErrorPageConfigurator = new DefaultErrorPageConfigurator()
+ })
+
+ it('Tests the method configure', () => {
+ customDefaultErrorPageConfigurator.configure({
+ defaultPages: {
+ clientErrorPage: default404
+ }
+ })
+ })
+
+ it('Tests the method clientErrorPage', () => {
+ defaultErrorPageConfigurator.manager.clientErrorPage({}, fakeResponse)
+ expect(fakeResponse.errorCode).to.be.equal(404)
+ expect(customDefaultErrorPageConfigurator.manager.clientErrorPage({}, fakeResponse)).to.be.equal(404)
+ })
+
+ it('Tests the method serverErrorPage', () => {
+ defaultErrorPageConfigurator.manager.serverErrorPage({}, fakeResponse)
+ expect(fakeResponse.errorCode).to.be.equal(500)
+ })
+})
diff --git a/test/specs/processor/Dispatcher.spec.js b/test/specs/processor/Dispatcher.spec.js
index 7a4d65d..746d0e0 100644
--- a/test/specs/processor/Dispatcher.spec.js
+++ b/test/specs/processor/Dispatcher.spec.js
@@ -1,5 +1,6 @@
/* eslint no-unused-expressions: 0 */
const Dispatcher = require(path.join(__root, './src/processor/Dispatcher'))
+const DefaultErrorPageConfigurator = require(path.join(__root, './src/configuration/DefaultErrorPageConfigurator'))
/* Simulation values */
@@ -28,7 +29,8 @@ let fakeCherryInstance = {
}
}
}
- }
+ },
+ defaultErrorPageConfigurator: new DefaultErrorPageConfigurator()
}
let fakeRequest = {
url: 'http://localhost:3000/test',
@@ -44,10 +46,11 @@ let fakeRequest = {
boundDataToRequest: async () => {}
}
let fakeResponse = {
- writeHead (httpCode) {
+ html: () => {},
+ writeHead: (httpCode) => {
expect(httpCode).to.be.above(400)
},
- end (response) {
+ end: (response) => {
expect(typeof response).to.be.equal('string')
}
}