/**
* @module libflitter/errors/ErrorUnit
*/
const Unit = require('../Unit')
const HTTPError = require('./HTTPError')
/**
* The error unit defines last-resort handlers for HTTP 404 and HTTP
* 500 errors. This unit must be loaded after all other routes. If it
* isn't, it will preempt any other routes from working. The routes in
* this unit are used if no other path is found. The handler alters the
* status of the request to the HTTP error, then renders the appropriate
* view in the "views/errors/" directory.
*
* @extends module:libflitter/Unit~Unit
*/
class ErrorUnit extends Unit {
/**
* Defines the services required by this unit.
* @returns {Array<string>}
*/
static get services() {
return [...super.services, 'output', 'views']
}
/**
* Gets the name of the service provided by this unit: 'error_handling'
* @returns {string} - 'error_handling'
*/
static get name() {
return 'error_handling'
}
/**
* Loads the unit. Registers last-resort handlers for HTTP404 and HTTP500 errors with the underlying Express app.
* All HTTP errors are handled by rendering the view where the canonical name is 'errors:CODE' where 'CODE' is the
* numerical error code. If the 'server.environment' configuration is set to development, then all errors are handled
* by rendering the 'errors:development' view.
* @param {module:libflitter/app/FlitterApp~FlitterApp} app - the Flitter app
* @returns {Promise<void>}
*/
async go(app){
/*
* Tag 404 errors as a catch-all route.
*/
app.express.use((req, res, next) => {
let err = new HTTPError(404)
this.output.error(`HTTP 404 - ${req.path}`)
next(err)
})
/*
* Handle HTTP errors by rendering the corresponding
* view in views/errors/.
*/
app.express.use((err, req, res, next) => {
const status = err.status || 500
res.status(status)
this.output.error(`Internal Error (HTTP ${status} - ${req.path}) - ${err.message}`)
return this.views.error(res, status, { error: err })
})
}
}
module.exports = exports = ErrorUnit