Skip to content
Snippets Groups Projects
HttpError.js 2.22 KiB
/** @module core/errors/HttpError */

const { config } = require('bootstrap')
const { insecureHexString } = require('core/utils/crypto')

/**
 * @typedef {Object} HttpErrorPayload
 * @static
 *
 * @property {string} [id] A value that identifies this specific error instance.
 * defaults to a random 32 character string of hex digits
 *
 * @property {string} [status = "500"] The HTTP status that corresponds to this error
 *
 * @property {string} [code = "X-000"] An application-unique identifier code that corresponds
 * to the error _type_ (not the error instance like `id`)
 *
 * @property {string} [title = "An Error Occurred"] A short title that can give a brief
 * overview of what has gone wrong. Try to think of this value being shown in a list of other
 * errors for a guide on how it should come across - will glancing at this title give the reader
 * the information they need?
 *
 * @property {string} [description = "Something went wrong, but no reason was given"] A more
 * in-depth message that can go into details (if possible) about what went wrong, any possible
 * remediation steps and possibly useful links or information that could help resolve this
 * error
 */

/**
 * An error that can format itself as an error response payload
 * @extends Error
 * @see {@link https://nodejs.org/api/errors.html#errors_class_error}
 */
class HttpError extends Error {
	/**
	 * Create a new HttpError
	 *
	 * @param {module:core/errors/HttpError.HttpErrorPayload} params The error descriptor; should typically
	 * contain at least a `description` property, but most uses will override more of the
	 * defaults
	 */
	constructor(params) {
		const {
			id = insecureHexString(32),
			status = '500',
			code = 'X-000',
			title = 'An Error Occurred',
			description = 'Something went wrong, but no reason was given',
		} = params

		super(title)

		this.id = id
		this.status = status
		this.code = code
		this.title = title
		this.description = description
	}

	toJSON() {
		return {
			id: this.id,
			status: this.status,
			code: this.code,
			title: this.title,
			detail: config('app.dev') ?
				`${ this.description }\n\n${ this.stack }` :
				this.description,
		}
	}

	toString() {
		return JSON.stringify(this.toJSON(), null, 2)
	}
}

module.exports = HttpError