1.0.0 • Published 3 years ago

@htgabriel/server-errors v1.0.0

Weekly downloads
-
License
UNLICENSED
Repository
-
Last release
3 years ago

typescript-image jest-image npm-image

Installing

latest stable version:

yarn add @soufantech/server-errors

Usage

Some of the following examples shows usage within the expressjs framework, but server-errors isn't in any way bound to expressjs and can be used with virtually any framework (or none).

Examples show usage in JavaScript.

Using it out-of-the-box:

Throw the error somewhere in your app:

import { UnauthenticatedError } from '@soufantech/server-errors';

//...

if (!user) {
  throw new UnauthenticatedError(
    'You must be logged-in to perform this action!',
    {
      challenge: 'Basic',
    },
  );
}

Treat the error in your error-handler:

import { ServerError, InternalServerError } from '@soufantech/server-errors';

function errorHandler(err, req, res, next) {
  if (res.headersSent) {
    return next(err);
  }

  let responseError = err;

  // Turn error into an InternalServerError if it is neither an instance
  // ServerError nor a disclosable error (an error exposed to the client)
  if (!(err instanceof ServerError) || !err.isDisclosable) {
    responseError = new InternalServerError(err);
  }

  // Set header values, if any:
  Object.entries(responseError.headers || {}).forEach(([field, value]) => {
    res.set(field, value));
  });

  res.status(responseError.status);
  res.json({ error: responseError });
}

In the case above, the HTTP response will have a status code 401 (Unauthorized) and a header WWW-Authenticate set to Basic, along with the following body:

{
  "error": {
    "message": "You must be logged-in to perform this action!",
    "code": "Unauthenticated",
    "status": 401,
    "extensions": {
      "challenge": "Bearer"
    }
  }
}

Making your own errors

You can extend ServerError to make your own errors:

//
// errors.js
//

import { ServerError, disclosable } from '@soufantech/server-errors';

export class TeapotError extends ServerError {
  constructor(message, { content }) {
    super({
      message,
      status: 418,
      code: 'TeapotError'
    })

    this.extensions = { content };
  }
}

// Make the error disclosable if you want your clients to see it:
disclosable(TeapotError);

//
// some-controller.js
// 

import { TeapotError } from './errors';

// ...

  throw new TeapotError(
    'Server refused to brew coffee because it is teapot!'
    {
      content: 'Coffee',
    }
  );

Assuming you're handling your errors with the error-handler shown previously, the response body will look like this:

{
  "error": {
    "message": "Server refused to brew coffee because it is teapot!",
    "code": "TeapotError",
    "status": 418,
    "extensions": {
      "content": "Coffee"
    }
  }
}

That's it! You can peek the project files for more usage examples (see the test files for it) or for information on how to extend the types if you're using TypeScript.

TypeScript support

server-errors is built with TypeScript and thus TypeScript types are provided out-of-the-box. Although some features of server-errors are exclusive for TypeScript, you can take advantage of most of server-errors features if you're using JavaScript.

Documentation

server-errors provides an ever-increasing multitude of errors, such as NotFoundError, InvalidInputError, UnauthenticatedError, UnauthorizedError and many, many others. To see all the available errors and types, please refer to the source code.

Todo:

  • Add and configure semantic-release.