| 
									
										
										
										
											2018-08-31 16:04:04 +01:00
										 |  |  | // import { inspect } from 'util';
 | 
					
						
							|  |  |  | // import _ from 'lodash/fp';
 | 
					
						
							| 
									
										
										
										
											2015-08-04 01:25:34 -07:00
										 |  |  | import accepts from 'accepts'; | 
					
						
							| 
									
										
										
										
											2018-08-29 20:52:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-31 16:04:04 +01:00
										 |  |  | import { homeLocation } from '../../../config/env'; | 
					
						
							| 
									
										
										
										
											2018-08-29 20:52:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-13 11:39:07 -07:00
										 |  |  | import { unwrapHandledError } from '../utils/create-handled-error.js'; | 
					
						
							| 
									
										
										
										
											2015-08-04 01:25:34 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-27 16:41:42 -08:00
										 |  |  | const isDev = process.env.NODE_ENV !== 'production'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-31 16:04:04 +01:00
										 |  |  | // const toString = Object.prototype.toString;
 | 
					
						
							| 
									
										
										
										
											2017-12-27 16:41:42 -08:00
										 |  |  | // is full error or just trace
 | 
					
						
							|  |  |  | // _.toString(new Error('foo')) => "Error: foo
 | 
					
						
							|  |  |  | // Object.prototype.toString.call(new Error('foo')) => "[object Error]"
 | 
					
						
							| 
									
										
										
										
											2018-08-31 16:04:04 +01:00
										 |  |  | // const isInspect = val => !val.stack && _.toString(val) === toString.call(val);
 | 
					
						
							|  |  |  | // const stringifyErr = val => {
 | 
					
						
							|  |  |  | //   if (val.stack) {
 | 
					
						
							|  |  |  | //     return String(val.stack);
 | 
					
						
							|  |  |  | //   }
 | 
					
						
							| 
									
										
										
										
											2017-12-27 16:41:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-31 16:04:04 +01:00
										 |  |  | //   const str = String(val);
 | 
					
						
							| 
									
										
										
										
											2017-12-27 16:41:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-31 16:04:04 +01:00
										 |  |  | //   return isInspect(val) ?
 | 
					
						
							|  |  |  | //     inspect(val) :
 | 
					
						
							|  |  |  | //     str;
 | 
					
						
							|  |  |  | // };
 | 
					
						
							| 
									
										
										
										
											2017-12-27 16:41:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-31 16:04:04 +01:00
										 |  |  | // const createStackHtml = _.flow(
 | 
					
						
							|  |  |  | //   _.cond([
 | 
					
						
							|  |  |  | //     [isInspect, err => [err]],
 | 
					
						
							|  |  |  | //     // may be stack or just err.msg
 | 
					
						
							|  |  |  | //     [_.stubTrue, _.flow(stringifyErr, _.split('\n'), _.tail) ]
 | 
					
						
							|  |  |  | //   ]),
 | 
					
						
							|  |  |  | //   _.map(_.escape),
 | 
					
						
							|  |  |  | //   _.map(line => `<li>${line}</lin>`),
 | 
					
						
							|  |  |  | //   _.join('')
 | 
					
						
							|  |  |  | // );
 | 
					
						
							| 
									
										
										
										
											2017-12-27 16:41:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-31 16:04:04 +01:00
										 |  |  | // const createErrorTitle = _.cond([
 | 
					
						
							|  |  |  | //   [
 | 
					
						
							|  |  |  | //     _.negate(isInspect),
 | 
					
						
							|  |  |  | //     _.flow(stringifyErr, _.split('\n'), _.head, _.defaultTo('Error'))
 | 
					
						
							|  |  |  | //   ],
 | 
					
						
							|  |  |  | //   [_.stubTrue, _.constant('Error')]
 | 
					
						
							|  |  |  | // ]);
 | 
					
						
							| 
									
										
										
										
											2017-12-27 16:41:42 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | export default function prodErrorHandler() { | 
					
						
							| 
									
										
										
										
											2015-08-04 01:25:34 -07:00
										 |  |  |   // error handling in production.
 | 
					
						
							|  |  |  |   // disabling eslint due to express parity rules for error handlers
 | 
					
						
							| 
									
										
										
										
											2018-08-31 16:04:04 +01:00
										 |  |  |   return function(err, req, res, next) { | 
					
						
							|  |  |  |     // eslint-disable-line
 | 
					
						
							| 
									
										
										
										
											2017-12-28 11:19:31 -08:00
										 |  |  |     const handled = unwrapHandledError(err); | 
					
						
							|  |  |  |     // respect handled error status
 | 
					
						
							|  |  |  |     let status = handled.status || err.status || res.statusCode; | 
					
						
							|  |  |  |     if (!handled.status && status < 400) { | 
					
						
							|  |  |  |       status = 500; | 
					
						
							| 
									
										
										
										
											2015-08-04 01:25:34 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-12-28 11:19:31 -08:00
										 |  |  |     res.status(status); | 
					
						
							| 
									
										
										
										
											2015-08-04 01:25:34 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // parse res type
 | 
					
						
							| 
									
										
										
										
											2016-07-16 10:40:14 -07:00
										 |  |  |     const accept = accepts(req); | 
					
						
							|  |  |  |     const type = accept.type('html', 'json', 'text'); | 
					
						
							| 
									
										
										
										
											2015-08-04 01:25:34 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-29 20:52:41 +01:00
										 |  |  |     const redirectTo = handled.redirectTo || `${homeLocation}/`; | 
					
						
							| 
									
										
										
										
											2018-08-31 16:04:04 +01:00
										 |  |  |     const message = | 
					
						
							|  |  |  |       handled.message || 'Oops! Something went wrong. Please try again later'; | 
					
						
							| 
									
										
										
										
											2017-12-27 16:41:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-27 17:34:56 -08:00
										 |  |  |     if (isDev) { | 
					
						
							|  |  |  |       console.error(err); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-04 01:25:34 -07:00
										 |  |  |     if (type === 'html') { | 
					
						
							| 
									
										
										
										
											2015-08-16 15:26:43 -07:00
										 |  |  |       if (typeof req.flash === 'function') { | 
					
						
							| 
									
										
										
										
											2018-01-12 14:16:33 -08:00
										 |  |  |         req.flash(handled.type || 'danger', message); | 
					
						
							| 
									
										
										
										
											2015-08-16 15:26:43 -07:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-08-30 15:27:53 +01:00
										 |  |  |       return res.redirectWithFlash(redirectTo); | 
					
						
							| 
									
										
										
										
											2015-08-04 01:25:34 -07:00
										 |  |  |       // json
 | 
					
						
							|  |  |  |     } else if (type === 'json') { | 
					
						
							|  |  |  |       res.setHeader('Content-Type', 'application/json'); | 
					
						
							|  |  |  |       return res.send({ | 
					
						
							| 
									
										
										
										
											2018-01-01 15:39:14 -08:00
										 |  |  |         type: handled.type || 'errors', | 
					
						
							| 
									
										
										
										
											2017-07-13 11:39:07 -07:00
										 |  |  |         message | 
					
						
							| 
									
										
										
										
											2015-08-04 01:25:34 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  |       // plain text
 | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       res.setHeader('Content-Type', 'text/plain'); | 
					
						
							|  |  |  |       return res.send(message); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } |