This package contains a list of standard HTTP exceptions for Typescript. They can be emitted from a Node.js web application written in for example Koa or Curveball, or they can be re-used in a HTTP client.
This package exists because I often find myself re-writing errors such as:
classNotFoundextendsError{consthttpStatus=404;}Instead of doing this over an over again for every client and server-sideproject, it made more sense to be to create 1 generic package that I can re-use for every project I'm working on.
I had trouble finding something similar on NPM, so I hope this is useful to others.
This package has 0 dependencies and is not a part of any frameworks. Someone could use this package and integrate it into their own frameworks as a middleware.
The hope is that as long as this package is independent, it could be used by library authors to throw generic errors with HTTP error information.
npm install @curveball/http-errors
After installing the NPM package, you can very easily reference all the exceptions contained within:
import{NotFound,Forbidden}from'@curveball/http-errors';thrownewNotFound('Article not found');This also works fine with plain javascript:
const{ NotFound, Forbidden }=require('@curveball/http-errors');thrownewForbidden('You\'re not allowed to update this article');The library also ships with a simple utility function to see if any error has HTTP error information:
import{isHttpError}from'@curveball/http-errors';constmyError=newError('Custom error');myError.httpStatus=500;console.log(isHttpError(myError));The idea is that as long as libraries follow this pattern, they don't need to depend on this library but they can be used automatically by middlewares.
Built-in Error classes such as NotFound, Unauthorized, all have a title
property with the default HTTP error string.
constmyError=newMethodNotAllowed('I can\'t believe youi\'ve done this');console.log(myError.title);// Emits "Method Not Allowed"It also has a utility function to see if something was a Client or Server error:
import{BadRequest,isServerError,isClientError}from'@curveball/http-errors';constmyError=newBadRequest('I didn\'t understand it');console.log(isClientError(e));// trueconsole.log(isServerError(e));// falseLastly, a few HTTP responses require or suggest including extra HTTP headers with
more information about the error. For example, the 405 Method Not Allowed
response should include an Allow header, and the 503 Service Unavailable
should have a Retry-After header. The built-in error classes include support
these:
import{MethodNotAllowed,ServiceUnavailable}from'@curveball/http-errors';try{thrownewMethodNotAllowed('Not allowed',['GET','PUT']);}catch(e){console.log(e.allow);}try{thrownewServiceUnavailable('Not open on sundays',3600*24);}catch(e){console.log(e.retryAfter);}Lastly, it the package has an interface that makes it easier to work with the
application/problem+json format, as defined in RFC9457. The interface
has type, title, detail and instance properties, which makes it easier
to write a generic interface that emits this JSON error format.
exportfunctionisHttpError(e: Error): e is HttpError;exportfunctionisHttpProblem(e: Error): e is HttpProblem;exportfunctionisClientError(e: Error): boolean;exportfunctionisServerError(e: Error): boolean;exportinterfaceHttpErrorextendsError{httpStatus: number;}exportinterfaceHttpProblemextendsHttpError{type: string|null;title: string;detail: string|null;instance: string|null;}exportclassHttpErrorBaseextendsErrorimplementsHttpProblem{type: string|null=null;httpStatus: number=500;title: string='Internal Server Error';detail: string|null=null;instance: string|null=null;constructor(detail: string|null=null){}}exportclassBadRequestextendsHttpErrorBase{}typeAuthenticateChallenge=string|string[];exportclassUnauthorizedextendsHttpErrorBase{wwwAuthenticate: AuthenticateChallenge;constructor(detail: string|null=null,wwwAuthenticate?: AuthenticateChallenge){}}exportclassPaymentRequiredextendsHttpErrorBase{}exportclassForbiddenextendsHttpErrorBase{}exportclassNotFoundextendsHttpErrorBase{}exportclassMethodNotAllowedextendsHttpErrorBase{allow: string[]constructor(detail: string|null=null,allow?: string[]){}}exportclassNotAcceptableextendsHttpErrorBase{}exportclassProxyAuthenticationRequiredextendsHttpErrorBase{proxyAuthenticate: AuthenticateChallenge;constructor(detail: string|null=null,proxyAuthenticate?: AuthenticateChallenge){}}exportclassRequestTimeoutextendsHttpErrorBase{}exportclassConflictextendsHttpErrorBase{}exportclassGoneextendsHttpErrorBase{}exportclassLengthRequiredextendsHttpErrorBase{}exportclassPreconditionFailedextendsHttpErrorBase{}exportclassContentTooLargeextendsHttpErrorBase{retryAfter: number|null;constructor(detail: string|null=null,retryAfter: number|null=null){}}exportclassUriTooLongextendsHttpErrorBase{}exportclassUnsupportedMediaTypeextendsHttpErrorBase{}exportclassRangeNotSatisfiableextendsHttpErrorBase{}exportclassExpectationFailedextendsHttpErrorBase{}exportclassMisdirectedRequestextendsHttpErrorBase{}exportclassUnprocessableContentextendsHttpErrorBase{}exportclassLockedextendsHttpErrorBase{}exportclassFailedDependencyextendsHttpErrorBase{}exportclassTooEarlyextendsHttpErrorBase{}exportclassUpgradeRequiredextendsHttpErrorBase{}exportclassPreconditionRequiredextendsHttpErrorBase{}exportclassTooManyRequestsextendsHttpErrorBase{retryAfter: number|null;constructor(detail: string|null=null,retryAfter: number|null=null){}}exportclassRequestHeaderFieldsTooLargeextendsHttpErrorBase{}exportclassUnavailableForLegalReasonsextendsHttpErrorBase{}exportclassInternalServerErrorextendsHttpErrorBase{}exportclassNotImplementedextendsHttpErrorBase{}exportclassBadGatewayextendsHttpErrorBase{}exportclassServiceUnavailableextendsHttpErrorBase{retryAfter: number|null;constructor(detail: string|null=null,retryAfter: number|null=null){}}exportclassGatewayTimeoutextendsHttpErrorBase{}exportclassHttpVersionNotSupportedextendsHttpErrorBase{}exportclassVariantAlsoNegotiatesextendsHttpErrorBase{}exportclassUnsufficientStorageextendsHttpErrorBase{}exportclassLoopDetectedextendsHttpErrorBase{}exportclassNetworkAuthenticationRequiredextendsHttpErrorBase{}...