@@ -3,6 +3,7 @@ const path = require('path');
3
3
const process = require ( 'process' ) ;
4
4
const { Buffer } = require ( 'buffer' ) ;
5
5
6
+ const co = require ( 'co' ) ;
6
7
const Boom = require ( '@hapi/boom' ) ;
7
8
const camelCase = require ( 'camelcase' ) ;
8
9
const capitalize = require ( 'capitalize' ) ;
@@ -88,6 +89,7 @@ const passportLocalMongooseTooManyRequests = new Set([
88
89
//
89
90
90
91
function errorHandler (
92
+ cookiesKey = false ,
91
93
_logger = console ,
92
94
useCtxLogger = true , // useful if you have ctx.logger (e.g. you're using Cabin's middleware)
93
95
stringify = fastSafeStringify // you could alternatively use JSON.stringify
@@ -176,6 +178,9 @@ function errorHandler(
176
178
// check if there is a view rendering engine binding `this.render`
177
179
const hasRender = _isFunction ( this . render ) ;
178
180
181
+ // check if we're about to go into a possible endless redirect loop
182
+ const noReferrer = this . get ( 'Referrer' ) === '' ;
183
+
179
184
// populate the status and body with `boom` error message payload
180
185
// (e.g. you can do `ctx.throw(404)` and it will output a beautiful err obj)
181
186
err . status = err . status || 500 ;
@@ -219,7 +224,7 @@ function errorHandler(
219
224
} else {
220
225
this . body = _404 ;
221
226
}
222
- } else {
227
+ } else if ( noReferrer || this . status >= 500 ) {
223
228
// flash an error message
224
229
if ( hasFlash ) this . flash ( 'error' , err . message ) ;
225
230
@@ -234,6 +239,53 @@ function errorHandler(
234
239
} else {
235
240
this . body = _500 ;
236
241
}
242
+ } else {
243
+ //
244
+ // attempt to redirect the user back
245
+ //
246
+
247
+ // flash an error message
248
+ if ( hasFlash ) this . flash ( 'error' , err . message ) ;
249
+
250
+ // TODO: until the issue is resolved, we need to add this here
251
+ // <https://github.com/koajs/generic-session/pull/95#issuecomment-246308544>
252
+ if (
253
+ this . sessionStore &&
254
+ this . sessionId &&
255
+ this . session &&
256
+ cookiesKey
257
+ ) {
258
+ try {
259
+ await co
260
+ . wrap ( this . sessionStore . set )
261
+ . call ( this . sessionStore , this . sessionId , this . session ) ;
262
+ this . cookies . set ( cookiesKey , this . sessionId , this . session . cookie ) ;
263
+ } catch ( err ) {
264
+ logger . error ( err ) ;
265
+ if ( err . code === 'ERR_HTTP_HEADERS_SENT' ) return ;
266
+ }
267
+ }
268
+
269
+ /*
270
+ // TODO: we need to add support for `koa-session-store` here
271
+ // <https://github.com/koajs/generic-session/pull/95#issuecomment-246308544>
272
+ //
273
+ // these comments may no longer be valid and need reconsidered:
274
+ //
275
+ // if we're using `koa-session-store` we need to add
276
+ // `this._session = new Session()`, and then run this:
277
+ await co.wrap(this._session._store.save).call(
278
+ this._session._store,
279
+ this._session._sid,
280
+ stringify(this.session)
281
+ );
282
+ this.cookies.set(this._session._name, stringify({
283
+ _sid: this._session._sid
284
+ }), this._session._cookieOpts);
285
+ */
286
+
287
+ // redirect the user to the page they were just on
288
+ this . redirect ( 'back' ) ;
237
289
}
238
290
239
291
break ;
0 commit comments