Skip to content

Commit a44711b

Browse files
authored
Merge pull request #57 from osher/patch-1
use request logger whenever it's available
2 parents 90f8dcd + 73f7557 commit a44711b

File tree

2 files changed

+137
-13
lines changed

2 files changed

+137
-13
lines changed

fittings/json_error_handler.js

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,50 @@ module.exports = function create(fittingDef, bagpipes) {
1212
if (!util.isError(context.error)) { return next(); }
1313

1414
var err = context.error;
15+
var log;
16+
var body;
1517

1618
debug('exec: %s', context.error.message);
17-
18-
try {
19-
if (!context.statusCode || context.statusCode < 400) {
20-
if (context.response && context.response.statusCode && context.response.statusCode >= 400) {
21-
context.statusCode = context.response.statusCode;
22-
} else if (err.statusCode && err.statusCode >= 400) {
23-
context.statusCode = err.statusCode;
24-
delete(err.statusCode);
25-
} else {
26-
context.statusCode = 500;
27-
}
19+
20+
if (!context.statusCode || context.statusCode < 400) {
21+
if (context.response && context.response.statusCode && context.response.statusCode >= 400) {
22+
context.statusCode = context.response.statusCode;
23+
} else if (err.statusCode && err.statusCode >= 400) {
24+
context.statusCode = err.statusCode;
25+
delete(err.statusCode);
26+
} else {
27+
context.statusCode = 500;
2828
}
29+
}
2930

31+
try {
32+
//TODO: find what's throwing here...
3033
if (context.statusCode === 500 && !fittingDef.handle500Errors) { return next(err); }
34+
//else - from here we commit to emitting error as JSON, no matter what.
3135

3236
context.headers['Content-Type'] = 'application/json';
3337
Object.defineProperty(err, 'message', { enumerable: true }); // include message property in response
3438

3539
delete(context.error);
3640
next(null, JSON.stringify(err));
3741
} catch (err2) {
38-
debug('jsonErrorHandler unable to stringify error: %j', err);
39-
next();
42+
log = context.request && (
43+
context.request.log
44+
|| context.request.app && context.request.app.log
45+
)
46+
|| context.response && context.response.log;
47+
48+
body = {
49+
message: "unable to stringify error properly",
50+
stringifyErr: err2.message,
51+
originalErrInspect: util.inspect(err)
52+
};
53+
context.statusCode = 500;
54+
55+
debug('jsonErrorHandler unable to stringify error: ', err);
56+
if (log) log.error(err2, "onError: json_error_handler - unable to stringify error", err);
57+
58+
next(null, JSON.stringify(body));
4059
}
4160
}
4261
};

test/fittings/json_error_handler.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,111 @@ describe('json_error_handler', function() {
124124
});
125125
});
126126

127+
describe('handle500Errors:true and error fails to stringify', function() {
128+
var jsonErrorHandler;
129+
var mockErr;
130+
var context;
131+
var err;
132+
133+
before(function() {
134+
jsonErrorHandler = json_error_handler({ handle500Errors: true });
135+
mockErr = new Error('this is a test');
136+
mockErr.circular = mockErr; //force stringification error
137+
});
138+
139+
describe('and context has a logger on request', function() {
140+
before(function(done) {
141+
context = {
142+
headers: {},
143+
request: {
144+
log: {
145+
error: function() { this.lastErr = arguments }
146+
}
147+
},
148+
error: mockErr
149+
};
150+
jsonErrorHandler(context, function(e) {
151+
err = e;
152+
done()
153+
});
154+
});
155+
it('should not fail', function() {
156+
should.not.exist(err);
157+
})
158+
it('should remove the error from the context', function() {
159+
should.not.exist(context.error);
160+
});
161+
it('should pass stringification error to the logger', function() {
162+
should.exist(context.request.log.lastErr, "error was not passed to log");
163+
should(context.request.log.lastErr.length).eql(3);
164+
should(context.request.log.lastErr[2]).equal(mockErr);
165+
});
166+
});
167+
168+
describe('and context has no logger on req.log, but has on request.app.log', function() {
169+
before(function(done) {
170+
context = {
171+
headers: {},
172+
request: {
173+
app: {
174+
log: {
175+
error: function() { this.lastErr = arguments }
176+
}
177+
}
178+
},
179+
error: mockErr
180+
};
181+
jsonErrorHandler(context, function(e) {
182+
err = e;
183+
done()
184+
});
185+
});
186+
it('should not fail', function() {
187+
should.not.exist(err);
188+
})
189+
it('should remove the error from the context', function() {
190+
should.not.exist(context.error);
191+
});
192+
it('should pass stringification error to the logger', function() {
193+
should.exist(context.request.app.log.lastErr, "error was not passed to log");
194+
should(context.request.app.log.lastErr.length).eql(3);
195+
should(context.request.app.log.lastErr[2]).equal(mockErr);
196+
});
197+
});
198+
199+
describe('and context has no logger on request, but has on response', function() {
200+
201+
beforeEach(function(done) {
202+
context = {
203+
headers: {},
204+
response: {
205+
log: {
206+
error: function() { this.lastErr = arguments }
207+
}
208+
},
209+
error: mockErr
210+
};
211+
jsonErrorHandler(context, function(e) {
212+
err = e;
213+
done()
214+
});
215+
216+
});
127217

218+
it('should not fail', function() {
219+
should.not.exist(err);
220+
});
221+
it('should remove the error from the context', function() {
222+
should.not.exist(context.error);
223+
});
224+
it('should pass stringification error to the logger', function() {
225+
should.exist(context.response.log.lastErr, "error was not passed to log");
226+
should(context.response.log.lastErr.length).eql(3);
227+
should(context.response.log.lastErr[2]).equal(mockErr);
228+
});
229+
});
230+
});
231+
128232

129233
describe('no error in context', function() {
130234

@@ -160,4 +264,5 @@ describe('json_error_handler', function() {
160264
});
161265
});
162266
});
267+
163268
});

0 commit comments

Comments
 (0)