File tree 4 files changed +61
-4
lines changed
4 files changed +61
-4
lines changed Original file line number Diff line number Diff line change @@ -195,7 +195,13 @@ module.exports = class Application extends Emitter {
195
195
*/
196
196
197
197
onerror ( err ) {
198
- if ( ! ( err instanceof Error ) ) throw new TypeError ( util . format ( 'non-error thrown: %j' , err ) ) ;
198
+ // When dealing with cross-globals a normal `instanceof` check doesn't work properly.
199
+ // See https://github.com/koajs/koa/issues/1466
200
+ // We can probably remove it once jest fixes https://github.com/facebook/jest/issues/2549.
201
+ const isNativeError =
202
+ Object . prototype . toString . call ( err ) === '[object Error]' ||
203
+ err instanceof Error ;
204
+ if ( ! isNativeError ) throw new TypeError ( util . format ( 'non-error thrown: %j' , err ) ) ;
199
205
200
206
if ( 404 === err . status || err . expose ) return ;
201
207
if ( this . silent ) return ;
Original file line number Diff line number Diff line change @@ -110,7 +110,13 @@ const proto = module.exports = {
110
110
// to node-style callbacks.
111
111
if ( null == err ) return ;
112
112
113
- if ( ! ( err instanceof Error ) ) err = new Error ( util . format ( 'non-error thrown: %j' , err ) ) ;
113
+ // When dealing with cross-globals a normal `instanceof` check doesn't work properly.
114
+ // See https://github.com/koajs/koa/issues/1466
115
+ // We can probably remove it once jest fixes https://github.com/facebook/jest/issues/2549.
116
+ const isNativeError =
117
+ Object . prototype . toString . call ( err ) === '[object Error]' ||
118
+ err instanceof Error ;
119
+ if ( ! isNativeError ) err = new Error ( util . format ( 'non-error thrown: %j' , err ) ) ;
114
120
115
121
let headerSent = false ;
116
122
if ( this . headerSent || ! this . writable ) {
Original file line number Diff line number Diff line change @@ -16,6 +16,18 @@ describe('app.onerror(err)', () => {
16
16
} , TypeError , 'non-error thrown: foo' ) ;
17
17
} ) ;
18
18
19
+ it ( 'should accept errors coming from other scopes' , ( ) => {
20
+ const ExternError = require ( 'vm' ) . runInNewContext ( 'Error' ) ;
21
+
22
+ const app = new Koa ( ) ;
23
+ const error = Object . assign ( new ExternError ( 'boom' ) , {
24
+ status : 418 ,
25
+ expose : true
26
+ } ) ;
27
+
28
+ assert . doesNotThrow ( ( ) => app . onerror ( error ) ) ;
29
+ } ) ;
30
+
19
31
it ( 'should do nothing if status is 404' , ( ) => {
20
32
const app = new Koa ( ) ;
21
33
const err = new Error ( ) ;
Original file line number Diff line number Diff line change 1
-
2
1
'use strict' ;
3
2
4
3
const assert = require ( 'assert' ) ;
@@ -205,6 +204,40 @@ describe('ctx.onerror(err)', () => {
205
204
} ) ;
206
205
} ) ;
207
206
207
+ describe ( 'when error from another scope thrown' , ( ) => {
208
+ it ( 'should handle it like a normal error' , async ( ) => {
209
+ const ExternError = require ( 'vm' ) . runInNewContext ( 'Error' ) ;
210
+
211
+ const app = new Koa ( ) ;
212
+ const error = Object . assign ( new ExternError ( 'boom' ) , {
213
+ status : 418 ,
214
+ expose : true
215
+ } ) ;
216
+ app . use ( ( ctx , next ) => {
217
+ throw error ;
218
+ } ) ;
219
+
220
+ const server = app . listen ( ) ;
221
+
222
+ const gotRightErrorPromise = new Promise ( ( resolve , reject ) => {
223
+ app . on ( 'error' , receivedError => {
224
+ try {
225
+ assert . strictEqual ( receivedError , error ) ;
226
+ resolve ( ) ;
227
+ } catch ( e ) {
228
+ reject ( e ) ;
229
+ }
230
+ } ) ;
231
+ } ) ;
232
+
233
+ await request ( server )
234
+ . get ( '/' )
235
+ . expect ( 418 ) ;
236
+
237
+ await gotRightErrorPromise ;
238
+ } ) ;
239
+ } ) ;
240
+
208
241
describe ( 'when non-error thrown' , ( ) => {
209
242
it ( 'should response non-error thrown message' , ( ) => {
210
243
const app = new Koa ( ) ;
@@ -248,7 +281,7 @@ describe('ctx.onerror(err)', () => {
248
281
} ) ;
249
282
250
283
app . use ( async ctx => {
251
- throw { key : 'value' } ; // eslint-disable-line no-throw-literal
284
+ throw { key : 'value' } ; // eslint-disable-line no-throw-literal
252
285
} ) ;
253
286
254
287
request ( app . callback ( ) )
You can’t perform that action at this time.
0 commit comments