Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

new-error

Package Overview
Dependencies
Maintainers
2
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

new-error - npm Package Compare versions

Comparing version 1.2.10 to 1.3.1

17

build/error-types/BaseError.d.ts
import ExtendableError from 'es6-error';
import { DeserializeOpts, IBaseError, IBaseErrorConfig, SerializedError, SerializedErrorSafe } from '../interfaces';
import { ConvertedType, ConvertFn, DeserializeOpts, IBaseError, IBaseErrorConfig, SerializedError, SerializedErrorSafe } from '../interfaces';
/**

@@ -19,2 +19,3 @@ * Improved error class.

protected _hasSafeMetadata: boolean;
protected _onConvert: ConvertFn | null;
constructor(message: string, config?: IBaseErrorConfig);

@@ -138,2 +139,16 @@ /**

/**
* Calls the user-defined `onConvert` function to convert the error into another type.
* If `onConvert` is not defined, then returns the error itself.
*/
convert<T = ConvertedType>(): T;
/**
* Returns true if the onConvert handler is defined
*/
hasOnConvertDefined(): boolean;
/**
* Set the onConvert handler for convert() calls.
* This can also be defined via the onConvert config property in the constructor.
*/
setOnConvert(convertFn: ConvertFn): void;
/**
* Helper method for use with fromJson()

@@ -140,0 +155,0 @@ * @param errInstance An error instance that extends BaseError

58

build/error-types/BaseError.js

@@ -20,2 +20,3 @@ "use strict";

this._config = config || {};
this._onConvert = this._config.onConvert || null;
}

@@ -195,3 +196,2 @@ /**

toJSON(fieldsToOmit = []) {
var _a;
let data = {

@@ -227,8 +227,12 @@ errId: this._errId,

});
fieldsToOmit === null || fieldsToOmit === void 0 ? void 0 : fieldsToOmit.forEach(item => {
delete data[item];
});
(_a = this._config.toJSONFieldsToOmit) === null || _a === void 0 ? void 0 : _a.forEach(item => {
delete data[item];
});
if (Array.isArray(fieldsToOmit)) {
fieldsToOmit.forEach(item => {
delete data[item];
});
}
if (Array.isArray(this._config.toJSONFieldsToOmit)) {
this._config.toJSONFieldsToOmit.forEach(item => {
delete data[item];
});
}
return data;

@@ -242,3 +246,2 @@ }

toJSONSafe(fieldsToOmit = []) {
var _a;
let data = {

@@ -265,11 +268,38 @@ errId: this._errId,

}
fieldsToOmit === null || fieldsToOmit === void 0 ? void 0 : fieldsToOmit.forEach(item => {
delete data[item];
});
(_a = this._config.toJSONSafeFieldsToOmit) === null || _a === void 0 ? void 0 : _a.forEach(item => {
delete data[item];
});
if (Array.isArray(fieldsToOmit)) {
fieldsToOmit.forEach(item => {
delete data[item];
});
}
if (Array.isArray(this._config.toJSONSafeFieldsToOmit)) {
this._config.toJSONSafeFieldsToOmit.forEach(item => {
delete data[item];
});
}
return data;
}
/**
* Calls the user-defined `onConvert` function to convert the error into another type.
* If `onConvert` is not defined, then returns the error itself.
*/
convert() {
if (this._onConvert) {
return this._onConvert(this);
}
return this;
}
/**
* Returns true if the onConvert handler is defined
*/
hasOnConvertDefined() {
return typeof this._onConvert === 'function';
}
/**
* Set the onConvert handler for convert() calls.
* This can also be defined via the onConvert config property in the constructor.
*/
setOnConvert(convertFn) {
this._onConvert = convertFn;
}
/**
* Helper method for use with fromJson()

@@ -276,0 +306,0 @@ * @param errInstance An error instance that extends BaseError

@@ -10,2 +10,8 @@ "use strict";

constructor(highLevelErrorDef, lowLevelErrorDef, config = {}) {
if (typeof highLevelErrorDef.onConvert === 'function') {
config.onConvert = highLevelErrorDef.onConvert;
}
if (typeof lowLevelErrorDef.onConvert === 'function') {
config.onConvert = lowLevelErrorDef.onConvert;
}
super(lowLevelErrorDef.message, config);

@@ -12,0 +18,0 @@ this.withErrorCode(highLevelErrorDef.code);

import { BaseError } from './error-types/BaseError';
import { BaseRegistryError } from './error-types/BaseRegistryError';
import { ErrorRegistry } from './ErrorRegistry';
import { IBaseError, SerializedError, SerializedErrorSafe, HighLevelError, LowLevelError, DeserializeOpts, GenerateLowLevelErrorOpts, GenerateHighLevelErrorOpts } from './interfaces';
import { IBaseError, SerializedError, SerializedErrorSafe, HighLevelError, LowLevelError, DeserializeOpts, GenerateLowLevelErrorOpts, GenerateHighLevelErrorOpts, ConvertedType, ConvertFn } from './interfaces';
export * from './utils';
export { BaseError, BaseRegistryError, ErrorRegistry, IBaseError, HighLevelError, LowLevelError, SerializedError, SerializedErrorSafe, DeserializeOpts, GenerateLowLevelErrorOpts, GenerateHighLevelErrorOpts };
export { BaseError, BaseRegistryError, ErrorRegistry, IBaseError, HighLevelError, LowLevelError, SerializedError, SerializedErrorSafe, DeserializeOpts, GenerateLowLevelErrorOpts, GenerateHighLevelErrorOpts, ConvertedType, ConvertFn };

@@ -5,2 +5,3 @@ /**

import { BaseRegistryError } from './error-types/BaseRegistryError';
import { BaseError } from './error-types/BaseError';
export interface HighLevelError {

@@ -24,2 +25,11 @@ /**

logLevel?: string | number;
/**
* Callback function to call when calling BaseError#convert().
*
* (baseError) => any type
*
* - If not defined, will return itself when convert() is called
* - If defined in HighLevelError, the HighLevelError definition takes priority
*/
onConvert?: ConvertFn;
}

@@ -60,2 +70,11 @@ /**

logLevel?: string | number;
/**
* Callback function to call when calling BaseError#convert().
*
* (baseError) => any type
*
* - If not defined, will return itself when convert() is called
* - This definition takes priority if HighLevelError#onConvert is defined
*/
onConvert?: ConvertFn;
}

@@ -131,2 +150,7 @@ /**

/**
* Set the onConvert handler for convert() calls.
* This can also be defined via the onConvert config property in the constructor.
*/
setOnConvert(convertFn: ConvertFn): void;
/**
* Attach the original error that was thrown, if available

@@ -200,2 +224,11 @@ * @param {Error} error

/**
* Calls the user-defined `onConvert` function to convert the error into another type.
* If `onConvert` is not defined, then returns the error itself.
*/
convert<T = ConvertedType>(): T;
/**
* Returns true if the onConvert handler is defined
*/
hasOnConvertDefined(): boolean;
/**
* Stack trace

@@ -231,2 +264,9 @@ */

onPreToJSONSafeData?: (data: Partial<SerializedErrorSafe>) => Partial<SerializedErrorSafe>;
/**
* A callback function to call when calling BaseError#convert(). This allows for user-defined conversion
* of the BaseError into some other type (such as an Apollo GraphQL error type).
*
* (baseError) => any type
*/
onConvert?: ConvertFn;
}

@@ -327,1 +367,3 @@ /**

}
export declare type ConvertedType = any;
export declare type ConvertFn = <E extends BaseError = BaseError>(err: E) => ConvertedType;

@@ -0,1 +1,11 @@

## 1.3.1 - Sun Mar 14 2021 03:09:54
**Contributor:** Theo Gravity
- Add the ability to convert an error to another type (#11)
This is useful if you need to convert the errors created by this library into another type, such as a `GraphQLError` when going outbound to the client.
See the README for more details.
## 1.2.10 - Fri Mar 12 2021 02:21:26

@@ -2,0 +12,0 @@

{
"name": "new-error",
"version": "1.2.10",
"version": "1.3.1",
"description": "A production-grade error creation and serialization library designed for Typescript",

@@ -5,0 +5,0 @@ "main": "build/index.js",

@@ -53,5 +53,8 @@ # new-error

- [Static methods](#static-methods)
- [Utility methods](#utility-methods)
- [Set an error id](#set-an-error-id)
- [Attaching errors](#attaching-errors)
- [Format messages](#format-messages)
- [Converting the error into another type](#converting-the-error-into-another-type)
- [Apollo GraphQL example](#apollo-graphql-example)
- [Adding metadata](#adding-metadata)

@@ -595,3 +598,3 @@ - [Safe metadata](#safe-metadata)

Generated errors extend the `BaseError` class, which supplies the manipulation methods.
Generated errors extend the `BaseError` class, which extends `Error`.

@@ -630,2 +633,9 @@ ## Constructor

onPreToJSONSafeData?: (data: Partial<SerializedErrorSafe>) => Partial<SerializedErrorSafe>
/**
* A callback function to call when calling BaseError#convert(). This allows for user-defined conversion
* of the BaseError into some other type (such as a Apollo GraphQL error type).
*
* (baseError) => any type
*/
onConvert?: <E extends BaseError = BaseError>(err: E) => any
}

@@ -636,2 +646,4 @@ ```

The following getters are included with the standard `Error` properties and methods:
- `BaseError#getErrorId()`

@@ -659,2 +671,3 @@ - `BaseError#getErrorName()`

- `BaseError#setConfig(config: IBaseErrorConfig): void`
- `BaseError#setOnConvert(<E extends BaseError = BaseError>(err: E) => any): void`

@@ -665,2 +678,7 @@ ## Static methods

## Utility methods
- `BaseError#convert<E = BaseError | any>() : E`
- `BaseError#hasOnConvertDefined(): boolean`
## Set an error id

@@ -713,2 +731,125 @@

The message can be accessed via the `.message` property.
## Converting the error into another type
Method: `BaseError#convert<T = any>() : T`
This is useful if you need to convert the error into another type. This type can be another error or some other data type.
### Apollo GraphQL example
For example, Apollo GraphQL prefers that any errors thrown from a GQL endpoint is an error that extends [`ApolloError`](https://www.apollographql.com/docs/apollo-server/data/errors/).
You might find yourself doing the following pattern if your resolver happens to throw a `BaseError`:
```ts
import { GraphQLError } from 'graphql';
import { BaseError } from 'new-error';
import { ApolloError, ForbiddenError } from 'apollo-server';
const server = new ApolloServer({
typeDefs,
resolvers,
formatError: (err: BaseError | ApolloError | GraphQLError | Error) => {
if (err instanceof BaseError) {
// re-map the BaseError into an Apollo error type
switch(err.getCode()) {
case 'PERMISSION_REQUIRED':
return new ForbiddenError(err.message)
default:
return new ApolloError(err.message)
}
}
return err;
},
});
```
Trying to switch for every single code / subcode can be cumbersome.
Instead of using this pattern, do the following so that your conversions can remain in one place:
```ts
import { GraphQLError } from 'graphql';
import { BaseError, ErrorRegistry } from 'new-error';
import { ApolloError, ForbiddenError } from 'apollo-server';
const errors = {
PERMISSION_REQUIRED: {
className: 'PermissionRequiredError',
code: 'PERMISSION_REQUIRED',
// Define a conversion function that is called when BaseError#convert() is called
// error is the BaseError
onConvert: (error) => {
return new ForbiddenError(error.message)
}
},
AUTH_REQUIRED: {
className: 'AuthRequiredError',
code: 'AUTH_REQUIRED'
// onConvert is not defined, so will return the error itself when convert() is called
}
}
const errorCodes = {
ADMIN_PANEL_RESTRICTED: {
message: 'Access scope required: admin',
// This will override the PERMISSION_REQUIRED / high level error handler when BaseError#convert() is called
onConvert: (error) => {
return new ForbiddenError('Admin required')
}
},
EDITOR_SECTION_RESTRICTED: {
message: 'Access scope required: editor',
// no onConvert function is defined, so will use the PERMISSION_REQUIRED / high level definition if defined
}
}
const errRegistry = new ErrorRegistry(errors, errorCodes)
const server = new ApolloServer({
typeDefs,
resolvers,
// errors thrown from the resolvers come here
formatError: (err: BaseError | ApolloError | GraphQLError | Error) => {
// If the error is a BaseError and the error has the onConvert handler defined
if (err instanceof BaseError && err.hasOnConvertDefined()) {
// Convert out to an Apollo error type
return err.convert()
}
return err;
},
});
const resolvers = {
Query: {
adminSettings(parent, args, context, info) {
// err.convert() will call onConvert() of ADMIN_PANEL_RESTRICTED (low level defs have higher priority)
throw errRegistry.newError('PERMISSION_REQUIRED', 'ADMIN_PANEL_RESTRICTED')
},
editorSettings(parent, args, context, info) {
// err.convert() will call onConvert() of PERMISSION_REQUIRED since EDITOR_SECTION_RESTRICTED does not
// have the onConvert defined
throw errRegistry.newError('PERMISSION_REQUIRED', 'EDITOR_SECTION_RESTRICTED')
},
checkAuth(parent, args, context, info) {
// err.convert() will return itself since onConvert() is not defined for either AUTH_REQUIRED or EDITOR_SECTION_RESTRICTED
throw errRegistry.newError('AUTH_REQUIRED', 'EDITOR_SECTION_RESTRICTED')
},
checkAuth2(parent, args, context, info) {
// err.convert() will return itself since onConvert() is not defined for either AUTH_REQUIRED
throw errRegistry.newBareError('AUTH_REQUIRED', 'Some error message')
},
permRequired(parent, args, context, info) {
// err.convert() will call onConvert() of PERMISSION_REQUIRED
throw errRegistry.newBareError('PERMISSION_REQUIRED', 'Some error message')
}
}
}
```
## Adding metadata

@@ -715,0 +856,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc