express.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. const _render = require('./page-renderer');
  2. const _path = require('path');
  3. const _fs = require('fs-magic');
  4. const _jsonReader = require('./json-reader');
  5. // wrapper to add custom options
  6. async function createDispatcher(options={}){
  7. // merge options
  8. const opt = {
  9. template: options.template || _path.join(__dirname, '../assets/template.ejs'),
  10. css: options.css || _path.join(__dirname, '../assets/layout.css'),
  11. lang: options.lang || 'en_US',
  12. footer: options.footer || null
  13. };
  14. // load page template
  15. const tpl = await _fs.readFile(opt.template, 'utf8');
  16. // load styles
  17. const css = await _fs.readFile(opt.css, 'utf8');
  18. // load page definitions
  19. const pages = await _jsonReader(_path.join(__dirname, '../i18n/pages-' + opt.lang + '.json'));
  20. // multi-type support
  21. // @see https://github.com/expressjs/express/blob/master/examples/error-pages/index.js
  22. return function dispatchRequest(page, httpStatusCode, req, res){
  23. // page available ?
  24. if (!pages[page]){
  25. // use "internal server error" as default
  26. page = '500';
  27. httpStatusCode = null;
  28. }
  29. // set http status code
  30. res.status(httpStatusCode || 500);
  31. // extract page date
  32. const pageData = pages[page];
  33. // multiple response formats
  34. res.format({
  35. // standard http-error-pages
  36. html: function(){
  37. res.type('.html');
  38. res.send(_render(tpl, css, {
  39. code: httpStatusCode,
  40. title: pageData.title,
  41. message: pageData.message,
  42. footer: opt.footer
  43. }))
  44. },
  45. // json
  46. json: function(){
  47. res.json({
  48. error: pageData.title + ' - ' + pageData.message
  49. })
  50. },
  51. // text response
  52. default: function(){
  53. // plain text
  54. res.type('.txt').send(pageData.title + ' - ' + pageData.message);
  55. }
  56. })
  57. }
  58. }
  59. module.exports = async function httpErrorPages(router, options={}){
  60. // create new disptacher with given options
  61. const dispatch = await createDispatcher(options);
  62. // default 404 error - no route matches
  63. router.all('*', function(req, res){
  64. dispatch('404', 404, req, res);
  65. });
  66. // internal errors (all)
  67. router.use(function(err, req, res, next){
  68. // status code given ?
  69. if (err.status){
  70. // custom errorpage set ?
  71. dispatch(err.errorpage || err.status, err.status, req, res);
  72. // use default http500 page
  73. }else{
  74. dispatch('500', 500, req, res);
  75. }
  76. });
  77. };