express.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. error: options.error || null,
  14. page_title: options.page_title || null
  15. };
  16. // load page template
  17. const tpl = await _fs.readFile(opt.template, 'utf8');
  18. // load styles
  19. const css = await _fs.readFile(opt.css, 'utf8');
  20. // load page definitions
  21. const pages = await _jsonReader(_path.join(__dirname, '../i18n/pages-' + opt.lang + '.json'));
  22. // multi-type support
  23. // @see https://github.com/expressjs/express/blob/master/examples/error-pages/index.js
  24. return function dispatchRequest(page, httpStatusCode, req, res){
  25. // page available ?
  26. if (!pages[page]){
  27. // use "internal server error" as default
  28. page = '500';
  29. httpStatusCode = null;
  30. }
  31. // set http status code
  32. res.status(httpStatusCode || 500);
  33. // extract page date
  34. const pageData = pages[page];
  35. // set page title
  36. let page_title = undefined;
  37. if(opt && opt.page_title) {
  38. page_title = opt.page_title.replace('%code%', page);
  39. page_title = page_title.replace('%title%', pageData.title);
  40. }
  41. // set error
  42. let error = 'Error '+ page
  43. if(opt && opt.error) {
  44. error = opt.error.replace('%code%', page);
  45. }
  46. // multiple response formats
  47. res.format({
  48. // standard http-error-pages
  49. html: function(){
  50. res.type('.html');
  51. res.send(_render(tpl, css, {
  52. code: httpStatusCode,
  53. title: pageData.title,
  54. message: pageData.message,
  55. footer: opt.footer,
  56. lang: opt.lang.substr(0, 2),
  57. error: error,
  58. page_title: page_title
  59. }))
  60. },
  61. // json
  62. json: function(){
  63. res.json({
  64. error: pageData.title + ' - ' + pageData.message
  65. })
  66. },
  67. // text response
  68. default: function(){
  69. // plain text
  70. res.type('.txt').send(pageData.title + ' - ' + pageData.message);
  71. }
  72. })
  73. }
  74. }
  75. module.exports = async function httpErrorPages(router, options={}){
  76. // create new disptacher with given options
  77. const dispatch = await createDispatcher(options);
  78. // default 404 error - no route matches
  79. router.all('*', function(req, res){
  80. dispatch('404', 404, req, res);
  81. });
  82. // internal errors (all)
  83. router.use(function(err, req, res, next){
  84. // status code given ?
  85. if (err.status){
  86. // custom errorpage set ?
  87. dispatch(err.errorpage || err.status, err.status, req, res);
  88. // use default http500 page
  89. }else{
  90. dispatch('500', 500, req, res);
  91. }
  92. });
  93. };