/**
 * This file defines error classes based on their semantic meaning. It abstracts away
 * HTTP status codes so they can be used in a RESTful way without worrying about a
 * consistent error interface.
 *
 * These classes descend from the base Error class, so they also automatically capture
 * stack traces--useful for debugging.
 */ import { Request , Response , NextFunction } from 'express' ; import { Logger } from '../../Logger' ; /**
 * Base error class.
 *
 * Supports HTTP status codes and a custom message.
 * From the ACM Membership Portal Backend repository
 */ export class HttpError extends Error { constructor ( public status , message ) { super ( message . toString ( ) ) ; this . name = this . constructor . name ; this . status = status ; this . message = message . toString ( ) ; } } export class UserError extends HttpError { constructor ( message ) { super ( 200 , message || 'User Error' ) ; } } export class BadRequest extends HttpError { constructor ( message ) { super ( 400 , message || 'Bad Request' ) ; } } export class Unauthorized extends HttpError { constructor ( message ) { super ( 401 , message || 'Unauthorized' ) ; } } export class Forbidden extends HttpError { constructor ( message ) { super ( 403 , message || 'Permission denied' ) ; } } export class NotFound extends HttpError { constructor ( message ) { super ( 404 , message || 'Resource not found' ) ; } } export class Unprocessable extends HttpError { constructor ( message ) { super ( 422 , message || 'Unprocessable request' ) ; } } export class InternalServerError extends HttpError { constructor ( message ) { super ( 500 , message || 'Internal server error' ) ; } } export class NotImplemented extends HttpError { constructor ( message ) { super ( 501 , message || 'Not Implemented' ) ; } } /**
 * General error handling middleware. Attaches to Express so that throwing or calling next() with
 * an error ends up here and all errors are handled uniformly.
 */ export const errorHandler = ( log ) => ( err , req , res , next ) : void => { if ( ! err ) err = new InternalServerError ( 'An unknown error occurred in the errorHandler' ) ; if ( ! err . status ) err = new InternalServerError ( err . message ) ; if ( err . status >= 500 ) { log . error ( `${ err . status }` , err ) ; } else { log . warn ( `${ err . status }: ${ err . message }` ) ; } res . status ( err . status ) . json ( { error : { status : err . status , message : `${ err . message }` , } , } ) ; } ;