koa.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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/koajs/koa/blob/master/docs/api/response.md#responseistypes
  22. return function dispatchRequest(page, httpStatusCode, ctx){
  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. ctx.status = httpStatusCode || 500;
  31. // extract page date
  32. const pageData = pages[page];
  33. // multiple response formats
  34. switch (ctx.accepts('json', 'html', 'text')){
  35. // jsonn response
  36. case 'json':
  37. ctx.type = 'json';
  38. ctx.body = {
  39. error: pageData.title + ' - ' + pageData.message
  40. }
  41. break;
  42. // html response
  43. case 'html':
  44. ctx.type = 'html';
  45. ctx.body = _render(tpl, css, {
  46. code: httpStatusCode,
  47. title: pageData.title,
  48. message: pageData.message,
  49. footer: opt.footer
  50. });
  51. break;
  52. // default: text response
  53. default:
  54. ctx.type = 'text/plain';
  55. ctx.body = pageData.title + ' - ' + pageData.message;
  56. }
  57. }
  58. }
  59. module.exports = async function httpErrorPages(options={}){
  60. // create new disptacher with given options
  61. const dispatch = await createDispatcher(options);
  62. // create error handler
  63. // @see https://github.com/koajs/koa/blob/master/docs/error-handling.md
  64. return async (ctx, next) => {
  65. try{
  66. // dispatch middleware chain
  67. await next();
  68. // route not found ?
  69. if (ctx.status === 404) {
  70. dispatch('404', 404, ctx);
  71. }
  72. }catch(err){
  73. // status code given ?
  74. if (err.status){
  75. // custom errorpage set ?
  76. dispatch(err.errorpage || err.status, err.status, ctx);
  77. // use default http500 page
  78. }else{
  79. dispatch('500', 500, ctx);
  80. }
  81. }
  82. }
  83. }