diff --git a/src/index.js b/src/index.js index cce9801..036c578 100644 --- a/src/index.js +++ b/src/index.js @@ -36,17 +36,24 @@ function fastbootExpressMiddleware(distPath, options) { result.html() .then(html => { let headers = result.headers; + let statusMessage = result.error ? 'NOT OK ' : 'OK '; for (var pair of headers.entries()) { res.set(pair[0], pair[1]); } - log(result.statusCode, 'OK ' + path); + if (result.error) { + log("RESILIENT MODE CAUGHT:", result.error.stack); + next(result.error); + } + + log(result.statusCode, statusMessage + path); res.status(result.statusCode); res.send(html); }) .catch(error => { - console.log(error.stack); + log(500, error.stack); + next(error); res.sendStatus(500); }); } @@ -55,6 +62,7 @@ function fastbootExpressMiddleware(distPath, options) { if (error.name === "UnrecognizedURLError") { next(); } else { + next(error); log(500, "Unknown Error: " + error.stack); if (error.stack) { res.status(500).send(error.stack); diff --git a/test/helpers/test-http-server.js b/test/helpers/test-http-server.js index 9631483..c268194 100644 --- a/test/helpers/test-http-server.js +++ b/test/helpers/test-http-server.js @@ -21,6 +21,13 @@ class TestHTTPServer { app.get('/*', this.middleware); + if (options.errorHandling) { + app.use((err, req, res, next) => { + res.set('x-test-error', 'error handler called'); + next(); + }); + } + return new Promise((resolve, reject) => { let port = options.port || 3000; let host = options.host || 'localhost'; @@ -42,9 +49,17 @@ class TestHTTPServer { }); } - request(urlPath) { + request(urlPath, options) { let info = this.info; let url = 'http://[' + info.host + ']:' + info.port; + + if (options && options.resolveWithFullResponse) { + return request({ + resolveWithFullResponse: options.resolveWithFullResponse, + uri: url + urlPath + }); + } + return request(url + urlPath); } diff --git a/test/middleware-test.js b/test/middleware-test.js index 5d74dec..ab300b2 100644 --- a/test/middleware-test.js +++ b/test/middleware-test.js @@ -65,7 +65,7 @@ describe("FastBoot", function() { }); }); - it("renders an empty page if the resilient flag is set", function() { + it("renders no FastBoot markup if the resilient flag is set", function() { let middleware = fastbootMiddleware({ distPath: fixture('rejected-promise'), resilient: true @@ -79,6 +79,54 @@ describe("FastBoot", function() { }); }); + it("propagates to error handling middleware if the resilient flag is set", function() { + let middleware = fastbootMiddleware({ + distPath: fixture('rejected-promise'), + resilient: true + }); + server = new TestHTTPServer(middleware, { errorHandling: true }); + + return server.start() + .then(() => server.request('/', { resolveWithFullResponse: true })) + .then(({ body, statusCode, headers }) => { + expect(statusCode).to.equal(200); + expect(headers['x-test-error']).to.match(/error handler called/); + expect(body).to.match(/hello world/); + }); + }); + + it("propagates to error handling middleware if the resilient flag is not set", function() { + let middleware = fastbootMiddleware({ + distPath: fixture('rejected-promise'), + resilient: false, + }); + server = new TestHTTPServer(middleware, { errorHandling: true }); + + return server.start() + .then(() => server.request('/', { resolveWithFullResponse: true })) + .catch(({ statusCode, response: { headers } }) => { + expect(statusCode).to.equal(500); + expect(headers['x-test-error']).to.match(/error handler called/); + }); + }); + + it("is does not propagate errors when the reslient flag is set and there is no error handling middleware", function() { + let middleware = fastbootMiddleware({ + distPath: fixture('rejected-promise'), + resilient: true, + }); + server = new TestHTTPServer(middleware, { errorHandling: false }); + + return server.start() + .then(() => server.request('/', { resolveWithFullResponse: true })) + .then(({ body, statusCode, headers }) => { + expect(statusCode).to.equal(200); + expect(headers['x-test-error']).to.not.match(/error handler called/); + expect(body).to.not.match(/error/); + expect(body).to.match(/hello world/); + }); + }); + it("can be provided with a custom FastBoot instance", function() { let fastboot = new FastBoot({ distPath: fixture('basic-app')