npm package: @switchcase/node-lerror
Description: Node Lambda Errors
Author: SwitchCase Group
Latest version: 1.0.5

# @switchcase/node-lerror

This NPM module is designed to help simplify the management of common HTTP error codes.

## Table of Contents

- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Building](#building)
- [Testing](#testing)
- [Deployment](#deployment)
- [Usage](#usage)

## Prerequisites

- [node](https://nodejs.org/en/) 12+ LTS


## Installation

```bash
yarn add @switchcase/node-lerror
```

## Building

```bash
yarn build
```

## Testing

```bash
yarn install
yarn test
```

## Usage

The intent of this module is to translate internal javascript API into consistent HTTP Error responses.

```javascript
// https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
export const handler = async (event: object = {}): Promise<object> => {
  console.log("Received event:", JSON.stringify(event, null, 2));
  const action = event.httpMethod;

  let body = event.body;
  if (event.isBase64Encoded === true) {
    const buff = new Buffer(event.body, "base64");
    body = buff.toString("utf8");
  }

  if (action === "POST") {
    console.log("handling POST calling processEvent");
    try {
      return await processEvent(body);
    } catch (e) {
      console.log("caught exception!", e);
      throw new BadRequestError("Something went wrong");
    }
  } else {
    console.log("throwing BadRequestError");
    throw new BadRequestError("Invalid action");
  }
};
```

### Error Contract

The following are the public properties availabe for these error classes.

| Property name | Type   | Meaning                                                                                                                        |
| ------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------ |
| name          | string | Programmatically-usable name of the error.                                                                                     |
| message       | string | Human-readable summary of the failure. Programmatically-accessible details are provided through VError.info(err) class method. |
| stack         | string | Human-readable stack trace where the Error was constructed.                                                                    |
| statusCode    | number | HTTP Status Code that should be presented for this error                                                                       |

```javascript
{
  name: 'NotFoundError',
  statusCode: 404 ,
  message: "File Not Found",
  stack: Error().stack
}
```

### Background

There are few different standards and conventions by Amazon API Gateway, Amazon Lambda, Node, Express, etc. that may conflict on how to handle errors and tracing such requests. The goal here is to create a single set of Error classes that incorporate the best practices and manages some of the details that will help us more consistently integrate with our observability and REST API contracts.

1.  Be clear about what your function does.
2.  Use Error objects (or subclasses) for all errors, and implement the Error contract.
3.  Use the Error's name property to distinguish errors programmatically.
4.  Augment the Error object with properties that explain details
5.  If you pass a lower-level error to your caller, consider wrapping it instead.

It recommend to standardize on the following property name, so they can be used further down the stack.

| Property name  | Intended use                                                                                                                                                              |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| localHostname  | the local DNS hostname (e.g., that you're accepting connections at)                                                                                                       |
| localIp        | the local IP address (e.g., that you're accepting connections at)                                                                                                         |
| localPort      | the local TCP port (e.g., that you're accepting connections at)                                                                                                           |
| remoteHostname | the DNS hostname of some other service (e.g., that you tried to connect to)                                                                                               |
| remoteIp       | the IP address of some other service (e.g., that you tried to connect to)                                                                                                 |
| remotePort     | the port of some other service (e.g., that you tried to connect to)                                                                                                       |
| path           | the name of a file, directory, or Unix Domain Socket (e.g., that you tried to open)                                                                                       |
| srcpath        | the name of a path used as a source (e.g., for a rename or copy)                                                                                                          |
| dstpath        | the name of a path used as a destination (e.g., for a rename or copy)                                                                                                     |
| hostname       | a DNS hostname (e.g., that you tried to resolve)                                                                                                                          |
| ip             | an IP address (e.g., that you tried to reverse-resolve)                                                                                                                   |
| propertyName   | an object property name, or an argument name (e.g., for a validation error)                                                                                               |
| propertyValue  | an object property value (e.g., for a validation error)                                                                                                                   |
| syscall        | the name of a system call that failed                                                                                                                                     |
| errno          | the symbolic value of errno (e.g., "ENOENT"). Do not use this for errors that don't actually set the C value of errno. Use "name" to distinguish between types of errors. |

This package builds on top of the [verror](https://www.npmjs.com/package/verror) NPM package.

### Reference

- [Node.js Production Practices: Error Handling in Node.js](https://www.joyent.com/node-js/production/design/errors)
- [Node.js documentation: Errors](https://nodejs.org/api/errors.html)
- [AWS Lambda Developer Guide: AWS Lambda function errors in Node.js](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-exceptions.html)
- [AWS Compute Blog: Error Handling Patterns in Amazon API Gateway and AWS Lambda (June 13th, 2016)](https://aws.amazon.com/blogs/compute/error-handling-patterns-in-amazon-api-gateway-and-aws-lambda/)
- [Github Gist: Creating custom Error classes in Node.JS](https://gist.github.com/justmoon/15511f92e5216fa2624b)
- [Error Tracing with ES6 Classes and Sentry (Agust 7th, 2020)](https://blog.dennisokeeffe.com/blog/2020-08-07-error-tracing-with-sentry-and-es6-classes)