Skip to content

Commit 73eb5d6

Browse files
author
Shogun
committed
feat: Initial commit.
0 parents  commit 73eb5d6

20 files changed

+1129
-0
lines changed

.circleci/config.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
version: 2.1
2+
orbs:
3+
codecov: codecov/codecov@1.0.2
4+
jobs:
5+
build:
6+
docker:
7+
# specify the version you desire here
8+
- image: circleci/node:lts
9+
working_directory: ~/repo
10+
steps:
11+
- checkout
12+
13+
# Download and cache dependencies
14+
- restore_cache:
15+
keys:
16+
- v1-dependencies-{{ checksum "package.json" }}
17+
# fallback to using the latest cache if no exact match is found
18+
- v1-dependencies-none
19+
20+
- run: yarn install
21+
22+
- save_cache:
23+
paths:
24+
- node_modules
25+
key: v1-dependencies-{{ checksum "package.json" }}
26+
27+
# Run the suite
28+
- run: yarn ci
29+
30+
# Store coverage informations
31+
- store_artifacts:
32+
path: coverage
33+
34+
# Upload to CodeCov
35+
- codecov/upload:
36+
file: coverage/coverage-final.json

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
coverage
2+
node_modules/
3+
package-lock.json
4+
yarn.lock

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### 2019-11-19 / 0.1.0
2+
3+
- Initial version.

LICENSE.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
ISC License
2+
3+
Copyright (c) 2019, and above Shogun <shogun@cowtech.it>
4+
5+
Permission to use, copy, modify, and/or distribute this software for any
6+
purpose with or without fee is hereby granted, provided that the above
7+
copyright notice and this permission notice appear in all copies.
8+
9+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

README.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# fastify-errors-properties
2+
3+
[![Package Version](https://img.shields.io/npm/v/fastify-errors-properties.svg)](https://npm.im/fastify-errors-properties)
4+
[![Dependency Status](https://img.shields.io/david/ShogunPanda/fastify-errors-properties)](https://david-dm.org/ShogunPanda/fastify-errors-properties)
5+
[![Build](https://img.shields.io/circleci/build/gh/ShogunPanda/fastify-errors-properties?token=a721161f936393ce2826774e8b89c0785c06967b)](https://circleci.com/gh/ShogunPanda/fastify-errors-properties)
6+
[![Code Coverage](https://img.shields.io/codecov/c/gh/ShogunPanda/fastify-errors-properties?token=d0ae1643f35c4c4f9714a357f796d05d)](https://codecov.io/gh/ShogunPanda/fastify-errors-properties)
7+
8+
A error handling plugin for Fastify that enables additional properties in errors.
9+
10+
http://sw.cowtech.it/fastify-errors-properties
11+
12+
## Installation
13+
14+
Just run:
15+
16+
```bash
17+
npm install fastify-errors-properties --save
18+
```
19+
20+
## Usage
21+
22+
Register as a plugin, optional providing any of the following options:
23+
24+
- `hideUnhandledErrors`: If to hide unhandled server errors or returning to the client including stack information. Default is to hide errors when `NODE_ENV` environment variable is `production`.
25+
26+
Once registered, the server will use the plugin handlers for all errors (basically, both `setErrorHandler` and `setNotFoundHandler` are called).
27+
28+
The handler response format will compatible with standard fastify error response, which is the following:
29+
30+
```typescript
31+
{
32+
statusCode: number
33+
code?: string
34+
error: string
35+
message: string
36+
}
37+
```
38+
39+
In addition, the response headers will contain all headers defined in `error.headers` and the response body will contain all additional enumerable properties of the error.
40+
41+
To clarify, take this server as a example:
42+
43+
```js
44+
const server = require('fastify')()
45+
const createError = require('http-errors')
46+
47+
server.register(require('fastify-errors-properties'))
48+
49+
server.get('/invalid', {
50+
handler: function(request, reply) {
51+
throw createError(404, 'You are not supposed to reach this.', { header: { 'X-Req-Id': request.id, id: 123 } })
52+
}
53+
})
54+
55+
server.listen(3000, err => {
56+
if (err) {
57+
throw err
58+
}
59+
})
60+
```
61+
62+
When hitting `/invalid` it will return the following:
63+
64+
```json
65+
{
66+
"error": "Not Found",
67+
"message": "You are not supposed to reach this.",
68+
"statusCode": 404,
69+
"id": 123
70+
}
71+
```
72+
73+
and the `X-Req-Id` will be set accordingly.
74+
75+
## Unhandled error handling
76+
77+
Once installed the plugin will also manage unhandled server errors.
78+
79+
In particular, if error hiding is enabled, all unhandled errors will return the following response:
80+
81+
```json
82+
{
83+
"error": "Internal Server Error",
84+
"message": "An error occurred trying to process your request.",
85+
"statusCode": 500
86+
}
87+
```
88+
89+
and the error will be logged using `error` severity.
90+
91+
If not hidden, instead, the error will be returned in a standard response that also add the `stack` property (as a array of strings) and any additional error enumerable property.
92+
93+
To clarify, take this server as a example:
94+
95+
```js
96+
const server = require('fastify')()
97+
const createError = require('http-errors')
98+
99+
server.register(require('fastify-errors-properties'), { hideUnhandledErrors: false })
100+
101+
server.get('/invalid', {
102+
handler: function(request, reply) {
103+
const error = new Error('This was not supposed to happen.')
104+
error.id = 123
105+
throw error
106+
}
107+
})
108+
109+
server.listen(3000, err => {
110+
if (err) {
111+
throw err
112+
}
113+
})
114+
```
115+
116+
When hitting `/invalid` it will return the following:
117+
118+
```json
119+
{
120+
"error": "Internal Server Error",
121+
"message": "This was not supposed to happen.",
122+
"statusCode": 500,
123+
"id": 123,
124+
"stack": ["..."]
125+
}
126+
```
127+
128+
## Contributing to fastify-errors-properties
129+
130+
- Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
131+
- Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
132+
- Fork the project.
133+
- Start a feature/bugfix branch.
134+
- Commit and push until you are happy with your contribution.
135+
- Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
136+
137+
## Copyright
138+
139+
Copyright (C) 2019 and above Shogun (shogun@cowtech.it).
140+
141+
Licensed under the ISC license, which can be found at https://choosealicense.com/licenses/isc.

lib/errors.js

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
"use strict";
2+
var __importDefault = (this && this.__importDefault) || function (mod) {
3+
return (mod && mod.__esModule) ? mod : { "default": mod };
4+
};
5+
Object.defineProperty(exports, "__esModule", { value: true });
6+
const http_errors_1 = __importDefault(require("http-errors"));
7+
const properties_1 = require("./properties");
8+
class ExtendedHttpError extends Error {
9+
constructor(message, properties) {
10+
super('');
11+
// Normalize arguments
12+
if (typeof message === 'object') {
13+
properties = message;
14+
message = undefined;
15+
}
16+
// Create a http-error with the same name and get its properties
17+
const standardError = new http_errors_1.default[this.constructor.name](message);
18+
const { status, statusCode, message: msg, headers, expose, stack } = standardError;
19+
// Assign properties - Use explicit assignment to avoid TS warning
20+
this.status = status;
21+
this.statusCode = statusCode;
22+
this.message = msg;
23+
this.headers = headers;
24+
this.expose = expose;
25+
this.stack = stack;
26+
// Assign additional properties
27+
if (properties) {
28+
properties_1.addAdditionalProperties(this, properties);
29+
}
30+
}
31+
}
32+
exports.ExtendedHttpError = ExtendedHttpError;
33+
// Keep these in sync with https://www.npmjs.com/package/http-errors
34+
class BadRequest extends ExtendedHttpError {
35+
}
36+
exports.BadRequest = BadRequest;
37+
class Unauthorized extends ExtendedHttpError {
38+
}
39+
exports.Unauthorized = Unauthorized;
40+
class PaymentRequired extends ExtendedHttpError {
41+
}
42+
exports.PaymentRequired = PaymentRequired;
43+
class Forbidden extends ExtendedHttpError {
44+
}
45+
exports.Forbidden = Forbidden;
46+
class NotFound extends ExtendedHttpError {
47+
}
48+
exports.NotFound = NotFound;
49+
class MethodNotAllowed extends ExtendedHttpError {
50+
}
51+
exports.MethodNotAllowed = MethodNotAllowed;
52+
class NotAcceptable extends ExtendedHttpError {
53+
}
54+
exports.NotAcceptable = NotAcceptable;
55+
class ProxyAuthenticationRequired extends ExtendedHttpError {
56+
}
57+
exports.ProxyAuthenticationRequired = ProxyAuthenticationRequired;
58+
class RequestTimeout extends ExtendedHttpError {
59+
}
60+
exports.RequestTimeout = RequestTimeout;
61+
class Conflict extends ExtendedHttpError {
62+
}
63+
exports.Conflict = Conflict;
64+
class Gone extends ExtendedHttpError {
65+
}
66+
exports.Gone = Gone;
67+
class LengthRequired extends ExtendedHttpError {
68+
}
69+
exports.LengthRequired = LengthRequired;
70+
class PreconditionFailed extends ExtendedHttpError {
71+
}
72+
exports.PreconditionFailed = PreconditionFailed;
73+
class PayloadTooLarge extends ExtendedHttpError {
74+
}
75+
exports.PayloadTooLarge = PayloadTooLarge;
76+
class URITooLong extends ExtendedHttpError {
77+
}
78+
exports.URITooLong = URITooLong;
79+
class UnsupportedMediaType extends ExtendedHttpError {
80+
}
81+
exports.UnsupportedMediaType = UnsupportedMediaType;
82+
class RangeNotSatisfiable extends ExtendedHttpError {
83+
}
84+
exports.RangeNotSatisfiable = RangeNotSatisfiable;
85+
class ExpectationFailed extends ExtendedHttpError {
86+
}
87+
exports.ExpectationFailed = ExpectationFailed;
88+
class ImATeapot extends ExtendedHttpError {
89+
}
90+
exports.ImATeapot = ImATeapot;
91+
class MisdirectedRequest extends ExtendedHttpError {
92+
}
93+
exports.MisdirectedRequest = MisdirectedRequest;
94+
class UnprocessableEntity extends ExtendedHttpError {
95+
}
96+
exports.UnprocessableEntity = UnprocessableEntity;
97+
class Locked extends ExtendedHttpError {
98+
}
99+
exports.Locked = Locked;
100+
class FailedDependency extends ExtendedHttpError {
101+
}
102+
exports.FailedDependency = FailedDependency;
103+
class UnorderedCollection extends ExtendedHttpError {
104+
}
105+
exports.UnorderedCollection = UnorderedCollection;
106+
class UpgradeRequired extends ExtendedHttpError {
107+
}
108+
exports.UpgradeRequired = UpgradeRequired;
109+
class PreconditionRequired extends ExtendedHttpError {
110+
}
111+
exports.PreconditionRequired = PreconditionRequired;
112+
class TooManyRequests extends ExtendedHttpError {
113+
}
114+
exports.TooManyRequests = TooManyRequests;
115+
class RequestHeaderFieldsTooLarge extends ExtendedHttpError {
116+
}
117+
exports.RequestHeaderFieldsTooLarge = RequestHeaderFieldsTooLarge;
118+
class UnavailableForLegalReasons extends ExtendedHttpError {
119+
}
120+
exports.UnavailableForLegalReasons = UnavailableForLegalReasons;
121+
class InternalServerError extends ExtendedHttpError {
122+
}
123+
exports.InternalServerError = InternalServerError;
124+
class NotImplemented extends ExtendedHttpError {
125+
}
126+
exports.NotImplemented = NotImplemented;
127+
class BadGateway extends ExtendedHttpError {
128+
}
129+
exports.BadGateway = BadGateway;
130+
class ServiceUnavailable extends ExtendedHttpError {
131+
}
132+
exports.ServiceUnavailable = ServiceUnavailable;
133+
class GatewayTimeout extends ExtendedHttpError {
134+
}
135+
exports.GatewayTimeout = GatewayTimeout;
136+
class HTTPVersionNotSupported extends ExtendedHttpError {
137+
}
138+
exports.HTTPVersionNotSupported = HTTPVersionNotSupported;
139+
class VariantAlsoNegotiates extends ExtendedHttpError {
140+
}
141+
exports.VariantAlsoNegotiates = VariantAlsoNegotiates;
142+
class InsufficientStorage extends ExtendedHttpError {
143+
}
144+
exports.InsufficientStorage = InsufficientStorage;
145+
class LoopDetected extends ExtendedHttpError {
146+
}
147+
exports.LoopDetected = LoopDetected;
148+
class BandwidthLimitExceeded extends ExtendedHttpError {
149+
}
150+
exports.BandwidthLimitExceeded = BandwidthLimitExceeded;
151+
class NotExtended extends ExtendedHttpError {
152+
}
153+
exports.NotExtended = NotExtended;
154+
class NetworkAuthenticationRequire extends ExtendedHttpError {
155+
}
156+
exports.NetworkAuthenticationRequire = NetworkAuthenticationRequire;

0 commit comments

Comments
 (0)