Skip to content

Commit 91e3c13

Browse files
author
Arjan Singh
committed
Allow post-fastboot middlewares to recover from fastboot failure
1 parent b975bb3 commit 91e3c13

File tree

3 files changed

+112
-74
lines changed

3 files changed

+112
-74
lines changed

src/index.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,16 @@ function fastbootExpressMiddleware(distPath, options) {
5353
})
5454
.catch(error => {
5555
log(500, error.stack);
56+
res.status(500);
5657
next(error);
57-
res.sendStatus(500);
5858
});
5959
}
6060

6161
function failure(error) {
62-
if (error.name === "UnrecognizedURLError") {
63-
next();
64-
} else {
65-
next(error);
66-
log(500, "Unknown Error: " + error.stack);
67-
if (error.stack) {
68-
res.status(500).send(error.stack);
69-
} else {
70-
res.sendStatus(500);
71-
}
62+
if (error.name !== "UnrecognizedURLError") {
63+
res.status(500);
7264
}
65+
next(error);
7366
}
7467
};
7568
}

test/helpers/test-http-server.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,15 @@ class TestHTTPServer {
2424
if (options.errorHandling) {
2525
app.use((err, req, res, next) => {
2626
res.set('x-test-error', 'error handler called');
27-
next();
27+
next(err);
28+
});
29+
}
30+
31+
if (options.recoverErrors) {
32+
app.use((err, req, res, next) => {
33+
res.set('x-test-recovery', 'recovered response');
34+
res.status(200);
35+
res.send('hello world');
2836
});
2937
}
3038

test/middleware-test.js

Lines changed: 99 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -65,68 +65,6 @@ describe("FastBoot", function() {
6565
});
6666
});
6767

68-
it("renders no FastBoot markup if the resilient flag is set", function() {
69-
let middleware = fastbootMiddleware({
70-
distPath: fixture('rejected-promise'),
71-
resilient: true
72-
});
73-
server = new TestHTTPServer(middleware);
74-
75-
return server.start()
76-
.then(() => server.request('/'))
77-
.then(html => {
78-
expect(html).to.not.match(/error/);
79-
});
80-
});
81-
82-
it("propagates to error handling middleware if the resilient flag is set", function() {
83-
let middleware = fastbootMiddleware({
84-
distPath: fixture('rejected-promise'),
85-
resilient: true
86-
});
87-
server = new TestHTTPServer(middleware, { errorHandling: true });
88-
89-
return server.start()
90-
.then(() => server.request('/', { resolveWithFullResponse: true }))
91-
.then(({ body, statusCode, headers }) => {
92-
expect(statusCode).to.equal(200);
93-
expect(headers['x-test-error']).to.match(/error handler called/);
94-
expect(body).to.match(/hello world/);
95-
});
96-
});
97-
98-
it("propagates to error handling middleware if the resilient flag is not set", function() {
99-
let middleware = fastbootMiddleware({
100-
distPath: fixture('rejected-promise'),
101-
resilient: false,
102-
});
103-
server = new TestHTTPServer(middleware, { errorHandling: true });
104-
105-
return server.start()
106-
.then(() => server.request('/', { resolveWithFullResponse: true }))
107-
.catch(({ statusCode, response: { headers } }) => {
108-
expect(statusCode).to.equal(500);
109-
expect(headers['x-test-error']).to.match(/error handler called/);
110-
});
111-
});
112-
113-
it("is does not propagate errors when the reslient flag is set and there is no error handling middleware", function() {
114-
let middleware = fastbootMiddleware({
115-
distPath: fixture('rejected-promise'),
116-
resilient: true,
117-
});
118-
server = new TestHTTPServer(middleware, { errorHandling: false });
119-
120-
return server.start()
121-
.then(() => server.request('/', { resolveWithFullResponse: true }))
122-
.then(({ body, statusCode, headers }) => {
123-
expect(statusCode).to.equal(200);
124-
expect(headers['x-test-error']).to.not.match(/error handler called/);
125-
expect(body).to.not.match(/error/);
126-
expect(body).to.match(/hello world/);
127-
});
128-
});
129-
13068
it("can be provided with a custom FastBoot instance", function() {
13169
let fastboot = new FastBoot({
13270
distPath: fixture('basic-app')
@@ -181,4 +119,103 @@ describe("FastBoot", function() {
181119
});
182120
}
183121
});
122+
123+
describe('when reslient mode is enabled', function () {
124+
it("renders no FastBoot markup", function() {
125+
let middleware = fastbootMiddleware({
126+
distPath: fixture('rejected-promise'),
127+
resilient: true
128+
});
129+
server = new TestHTTPServer(middleware);
130+
131+
return server.start()
132+
.then(() => server.request('/'))
133+
.then(html => {
134+
expect(html).to.not.match(/error/);
135+
});
136+
});
137+
138+
it("propagates to error handling middleware", function() {
139+
let middleware = fastbootMiddleware({
140+
distPath: fixture('rejected-promise'),
141+
resilient: true
142+
});
143+
server = new TestHTTPServer(middleware, { errorHandling: true });
144+
145+
return server.start()
146+
.then(() => server.request('/', { resolveWithFullResponse: true }))
147+
.then(({ body, statusCode, headers }) => {
148+
expect(statusCode).to.equal(200);
149+
expect(headers['x-test-error']).to.match(/error handler called/);
150+
expect(body).to.match(/hello world/);
151+
});
152+
});
153+
154+
it("is does not propagate errors when and there is no error handling middleware", function() {
155+
let middleware = fastbootMiddleware({
156+
distPath: fixture('rejected-promise'),
157+
resilient: true,
158+
});
159+
server = new TestHTTPServer(middleware, { errorHandling: false });
160+
161+
return server.start()
162+
.then(() => server.request('/', { resolveWithFullResponse: true }))
163+
.then(({ body, statusCode, headers }) => {
164+
expect(statusCode).to.equal(200);
165+
expect(headers['x-test-error']).to.not.match(/error handler called/);
166+
expect(body).to.not.match(/error/);
167+
expect(body).to.match(/hello world/);
168+
});
169+
});
170+
171+
it("allows post-fastboot middleware to recover the response when it fails", function() {
172+
let middleware = fastbootMiddleware({
173+
distPath: fixture('rejected-promise'),
174+
resilient: true
175+
});
176+
server = new TestHTTPServer(middleware, { recoverErrors: true });
177+
178+
return server.start()
179+
.then(() => server.request('/', { resolveWithFullResponse: true }))
180+
.then(({ body, statusCode, headers }) => {
181+
expect(statusCode).to.equal(200);
182+
expect(headers['x-test-recovery']).to.match(/recovered response/);
183+
expect(body).to.match(/hello world/);
184+
});
185+
});
186+
});
187+
188+
describe('when reslient mode is disabled', function () {
189+
it("propagates to error handling middleware", function() {
190+
let middleware = fastbootMiddleware({
191+
distPath: fixture('rejected-promise'),
192+
resilient: false,
193+
});
194+
server = new TestHTTPServer(middleware, { errorHandling: true });
195+
196+
return server.start()
197+
.then(() => server.request('/', { resolveWithFullResponse: true }))
198+
.catch(({ statusCode, response: { headers } }) => {
199+
expect(statusCode).to.equal(500);
200+
expect(headers['x-test-error']).to.match(/error handler called/);
201+
});
202+
});
203+
204+
it("allows post-fastboot middleware to recover the response when it fails", function() {
205+
let middleware = fastbootMiddleware({
206+
distPath: fixture('rejected-promise'),
207+
resilient: false
208+
});
209+
server = new TestHTTPServer(middleware, { recoverErrors: true });
210+
211+
return server.start()
212+
.then(() => server.request('/', { resolveWithFullResponse: true }))
213+
.then(({ body, statusCode, headers }) => {
214+
expect(statusCode).to.equal(200);
215+
expect(headers['x-test-recovery']).to.match(/recovered response/);
216+
expect(body).to.match(/hello world/);
217+
});
218+
});
219+
});
220+
184221
});

0 commit comments

Comments
 (0)