Socket
Socket
Sign inDemoInstall

erreur

Package Overview
Dependencies
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

erreur - npm Package Compare versions

Comparing version 2.0.0-5 to 2.0.0-6

34

dist/mod.d.ts

@@ -5,4 +5,4 @@ declare const INTERNAL: unique symbol;

declare type ErreurMap = Record<string, ErreurTypeAny>;
declare type ErreurTypeAny = ErreurType<any, any>;
declare type ErreurWithKind<Erreurs extends ErreurMap> = {
declare type ErreurTypeAny = ErreurDeclaration<any, any>;
declare type ErreurMapUnion<Erreurs extends ErreurMap> = {
[K in keyof Erreurs]: {

@@ -13,8 +13,12 @@ kind: K;

}[keyof Erreurs];
interface ErreurType<Data, Params extends readonly any[] = [Data]> {
/**
* This is like a key to instantiate an Erreur and extract its data
*/
interface ErreurDeclaration<Data, Params extends readonly any[] = [Data]> {
readonly [DATA]: Data;
readonly [INTERNAL]: symbol;
readonly name: string;
readonly withTransform: <Params extends readonly any[]>(transform: (...params: Params) => Data) => ErreurType<Data, Params>;
readonly withTransform: <Params extends readonly any[]>(transform: (...params: Params) => Data) => ErreurDeclaration<Data, Params>;
readonly create: (...params: Params) => Erreur;
readonly createWithCause: (cause: Erreur, ...params: Params) => Erreur;
readonly is: (error: unknown) => error is Erreur;

@@ -35,6 +39,8 @@ readonly match: (error: unknown) => Data | null;

static readonly matchObjOrThrow: typeof matchObjOrThrow;
static readonly createFromTypes: typeof createFromTypes;
static readonly createWithTransform: typeof createWithTransform;
static readonly createFromCreators: typeof createFromCreators;
static create<Data>(name: string): ErreurType<Data>;
static readonly declareWithTransform: typeof declareWithTransform;
static readonly declareManyFromTypes: typeof declareManyFromTypes;
static readonly declareMany: typeof declareMany;
readonly erreurCause?: Erreur;
cause?: Error | undefined;
static declare<Data>(name: string): ErreurDeclaration<Data>;
private constructor();

@@ -57,3 +63,3 @@ is(type: ErreurTypeAny): boolean;

declare function isOneOfObj(error: unknown, types: TypesBase): error is Erreur;
declare function match<Data>(error: unknown, type: ErreurType<Data>): Data | null;
declare function match<Data>(error: unknown, type: ErreurDeclaration<Data>): Data | null;
declare type TypesBase = Record<string, ErreurTypeAny>;

@@ -68,10 +74,10 @@ declare type DataFromTypes<Types extends TypesBase> = {

declare function matchObjOrThrow<Types extends TypesBase>(error: unknown, types: Types): DataFromTypes<Types>;
declare function createWithTransform<Data, Params extends readonly any[]>(name: string, transform: (...params: Params) => Data): ErreurType<Data, Params>;
declare function declareWithTransform<Data, Params extends readonly any[]>(name: string, transform: (...params: Params) => Data): ErreurDeclaration<Data, Params>;
declare type CreatorsBase = Record<string, (...args: any[]) => any>;
declare type ErreursFromCreators<Creators extends CreatorsBase> = {
[K in keyof Creators]: ErreurType<ReturnType<Creators[K]>, Parameters<Creators[K]>>;
[K in keyof Creators]: ErreurDeclaration<ReturnType<Creators[K]>, Parameters<Creators[K]>>;
};
declare function createFromCreators<Creators extends CreatorsBase>(creators: Creators): ErreursFromCreators<Creators>;
declare function createFromTypes<Errors extends Record<string, any>>(): <Creators extends { [K in keyof Errors]: (...args: any[]) => Errors[K]; }>(creators: Creators) => ErreursFromCreators<Creators>;
declare function declareMany<Creators extends CreatorsBase>(creators: Creators): ErreursFromCreators<Creators>;
declare function declareManyFromTypes<Errors extends Record<string, any>>(): <Creators extends { [K in keyof Errors]: (...args: any[]) => Errors[K]; }>(creators: Creators) => ErreursFromCreators<Creators>;
export { CreatorsBase, DataFromTypes, Erreur, ErreurMap, ErreurType, ErreurTypeAny, ErreurWithKind, ErreursFromCreators, OnError, TypesBase, resolve, resolveAsync, wrap, wrapAsync };
export { CreatorsBase, DataFromTypes, Erreur, ErreurDeclaration, ErreurMap, ErreurMapUnion, ErreurTypeAny, ErreursFromCreators, OnError, TypesBase, resolve, resolveAsync, wrap, wrapAsync };

@@ -33,10 +33,12 @@ var __defProp = Object.defineProperty;

constructor(internal) {
super(`[Erreur]: ${internal.type.name} ${JSON.stringify(internal.data)}`);
super(`[Erreur]: ${internal.declaration.name} ${JSON.stringify(internal.data)}`);
this[INTERNAL] = internal;
this.erreurCause = internal.erreurCause;
this.cause = internal.erreurCause;
Object.setPrototypeOf(this, new.target.prototype);
}
static create(name) {
static declare(name) {
const symbol = Symbol(`[Erreur]: ${name}`);
return createWithTransform2((data) => data);
function createWithTransform2(transform) {
return declareWithTransform2((data) => data);
function declareWithTransform2(transform) {
const type = {

@@ -46,6 +48,7 @@ [INTERNAL]: symbol,

name,
create: (...params) => new _Erreur({ type, data: transform(...params) }),
create: (...params) => new _Erreur({ declaration: type, data: transform(...params) }),
createWithCause: (cause, ...params) => new _Erreur({ declaration: type, data: transform(...params), erreurCause: cause }),
is: (error) => is(error, type),
match: (error) => match(error, type),
withTransform: (subTransform) => createWithTransform2(subTransform)
withTransform: (subTransform) => declareWithTransform2(subTransform)
};

@@ -74,5 +77,5 @@ return type;

Erreur.matchObjOrThrow = matchObjOrThrow;
Erreur.createFromTypes = createFromTypes;
Erreur.createWithTransform = createWithTransform;
Erreur.createFromCreators = createFromCreators;
Erreur.declareWithTransform = declareWithTransform;
Erreur.declareManyFromTypes = declareManyFromTypes;
Erreur.declareMany = declareMany;
function wrap(fn, onError) {

@@ -115,3 +118,3 @@ try {

if (type) {
return error[INTERNAL].type[INTERNAL] === type[INTERNAL];
return error[INTERNAL].declaration[INTERNAL] === type[INTERNAL];
}

@@ -124,3 +127,3 @@ return true;

if (error instanceof Erreur) {
return types.some((type) => error[INTERNAL].type[INTERNAL] === type[INTERNAL]);
return types.some((type) => error[INTERNAL].declaration[INTERNAL] === type[INTERNAL]);
}

@@ -131,3 +134,3 @@ return false;

if (error instanceof Erreur) {
return Object.values(types).some((type) => error[INTERNAL].type[INTERNAL] === type[INTERNAL]);
return Object.values(types).some((type) => error[INTERNAL].declaration[INTERNAL] === type[INTERNAL]);
}

@@ -138,3 +141,3 @@ return false;

if (error instanceof Erreur) {
if (error[INTERNAL].type[INTERNAL] === type[INTERNAL]) {
if (error[INTERNAL].declaration[INTERNAL] === type[INTERNAL]) {
return error[INTERNAL].data;

@@ -152,3 +155,3 @@ }

const type = types[key];
if (error[INTERNAL].type[INTERNAL] === type[INTERNAL]) {
if (error[INTERNAL].declaration[INTERNAL] === type[INTERNAL]) {
return { kind: key, data: error[INTERNAL].data };

@@ -166,15 +169,15 @@ }

}
function createWithTransform(name, transform) {
return Erreur.create(name).withTransform(transform);
function declareWithTransform(name, transform) {
return Erreur.declare(name).withTransform(transform);
}
function createFromCreators(creators) {
function declareMany(creators) {
const res = {};
for (const key of Object.keys(creators)) {
res[key] = Erreur.createWithTransform(key, creators[key]);
res[key] = declareWithTransform(key, creators[key]);
}
return res;
}
function createFromTypes() {
function declareManyFromTypes() {
return (creators) => {
return createFromCreators(creators);
return declareMany(creators);
};

@@ -181,0 +184,0 @@ }

{
"name": "erreur",
"version": "2.0.0-5",
"version": "2.0.0-6",
"description": "Type safe custom errors",

@@ -5,0 +5,0 @@ "keywords": [

@@ -5,94 +5,143 @@ # 🛑 Erreur

## Usage
## Type safe custom errors ?
This library allows you to create custom errors with type safety. It's composed of two classes:
This librairy expose a way to define and manipulate custom errors in a type safe way.
- `Erreur`: The custom error class.
- `ErreursMap`: A class to help you create a set of custom errors.
To acheive this, it uses a class called `Erreur` (error in french) that extends the native `Error` class. This class can contain data but in order to ensure type safety, you cannot access this data directly. Instead, you must use a declaration that can be created using the `Erreur.declare` static method.
## `Erreur`
Here is a simple example:
The `Erreur` class extends the base `Error` class and adds the following properties:
```ts
import { Erreur } from 'erreur';
- `kind`: A string that represents the kind of error.
- `infos`: An object that contains the `kind`, `message` and any additional information about the error
// Declare a new error with a type and a name
const MyError = Erreur.declare<{ message: string }>('MyError');
```typescript
type MyErreurInfos = {
kind: 'MyErreur';
message: string;
num: number;
};
// Use the declaration to create a new error
const error = MyError.create({ message: 'Hello world' });
const err = new Erreur<MyErreurInfos>({
kind: 'MyErreur',
message: 'Something went wrong',
num: 42,
});
// Use the declaration to extract the data from the error
const matched = MyError.match(error);
// matched has type { message: string } | null
```
expect(err.kind).toBe('MyErreur');
expect(err.infos).toEqual({
kind: 'MyErreur',
message: 'Something went wrong',
num: 42,
});
## API
### Declaring errors
#### `Erreur.declare`
The basic way to declare an error is to use the `Erreur.declare` static method. This method takes a type and a name as parameters and returns a declaration.
```ts
const MyError = Erreur.declare<{ message: string }>('MyError');
```
## `ErreursMap`
#### Transforms
The `ErreursMap` class allow you to define and manipulate a set of `Erreur`s.
The `withTransform` method of an `ErreurDeclaration` allows you to create a clone of the declaration that take custom parameters and transform them into the data of the error. Note that the original declaration is not modified and both declarations can be used to create errors (they are the same "key").
To create an `ErreursMap`, create a new instance with an object as parameter. Each property of the object should be a function that take any number of arguments and return an object with `message` and any additional information about the error.
```ts
const MyError = Erreur.declare<{ message: string }>('MyError');
const MyErrorWithTransform = MyError.withTransform((message: string) => ({ message }));
```typescript
const UserErreurs = new ErreursMap({
UnknownError: (error: Error) => ({ message: error.message, error }),
UserNotFound: (userId: string) => ({ message: 'User not found', userId }),
UserAlreadyExists: (username: string) => ({ message: 'User already exists', username }),
});
const err1 = MyError.create({ message: 'Hello world' });
const err2 = MyErrorWithTransform.create('Hello world');
// MyError.match(err1) === MyErrorWithTransform.match(err2) === { message: 'Hello world' }
```
### `.create`
You can also use `Erreur.declareWithTransform` to declare an error and apply a transform at the same time.
Once the `ErreursMap` created you can use it to create `Erreur` instances with `UserErreurs.create.[ErrorKind](...args)`:
```ts
const MyError = Erreur.declareWithTransform<{ message: string }>('MyError', (message: string) => ({
message,
}));
```typescript
const err = UserErreurs.create.UserAlreadyExists('paul-bocuse');
// TS will infer the type of the transform
const MyError = Erreur.declareWithTransform('MyError', (message: string) => ({ message }));
```
// err is an instance of Erreur
#### Decalaring multiple errors
The `Erreur.declareMany` let you declare multiple errors at the same time. It takes an object as parameter where the keys are the names of the errors and the values are transform functions.
```ts
const { MyError, MyOtherError } = Erreur.declareMany({
MyError: (message: string) => ({ message }),
MyOtherError: (num: number) => ({ num }),
});
```
### `.is`
You can also use the `Erreur.declareManyFromTypes` to declare multiple errors from a single type.
You can check wether an error is one of the errors defined in the `ErreursMap` with `UserErreurs.is(err)`:
```ts
interface MyErrors {
NumError: number;
FatalError: { message: string };
}
```typescript
UserErreurs.is(err); // true
// Note that declareManyFromTypes take no parameter and return a `declareMany` function
const { NumError, FatalError } = Erreur.declareManyFromTypes<MyErrors>()({
NumError: (num: number) => num,
FatalError: (message: string) => ({ message }),
});
```
**Note**: The `.is` check if the value is an instance of `Erreur` and if the `kind` is one of the errors defined in the `ErreursMap`.
#### `is`, `isOneOf` and `isOneOfObj`
### `.wrap`
The `Erreur.is` static method can be used to check if an value is an `Erreur`.
The `.wrap` method allow you to run code and return either teh result or one of the `Erreur` specified in the `ErreursMap`.
You can also pass a `ErreurDeclaration` as second parameter to check if the `Erreur` contains the declaration data.
The `.wrap` method takes two parameters:
```ts
const NumErreur = Erreur.declare<number>('NumErreur');
const BoolErreur = Erreur.declare<boolean>('BoolErreur');
- `fn`: The function to run.
- `mapOtherErr`: A function that will be used to transform any error that is not one of the `ErreursMap` errors into a valid one.
function handleError(err: unknown) {
if (Erreur.is(err)) {
// err is an Erreur
}
```typescript
const result = UserErreurs.wrap(
() => {
// this could throw
createNewUser();
},
(err) => UserErreurs.create.UnknownError(err)
);
if (Erreur.is(err, NumErreur)) {
// err is an Erreur and contains the data of NumErreur
}
// result is either an Erreur or the result of the function
if (Erreur.isOneOf(err, [NumErreur, BoolErreur])) {
// err is an Erreur and contains the data of either NumErreur or BoolErreur
}
if (Erreur.isOneOfObj(err, { NumErreur, BoolErreur })) {
// err is an Erreur and contains the data of either NumErreur or BoolErreur
}
}
```
### `.wrapAsync`
#### `match`, `matchObj` and `matchObjOrThrow`
The `.wrapAsync` method is similar to `.wrap` but it takes an async function instead of a regular function and returns a Promise.
This function is similar to `is` but instead of returning a boolean, it returns the data of the error if it matches the declaration.
Note that `matchObj` return an object with `{ kind: string, data: T }` where `kind` is the key of the declaration and `data` is the data of the error.
```ts
const NumErreur = Erreur.declare<number>('NumErreur');
const BoolErreur = Erreur.declare<boolean>('BoolErreur');
function handleError(err: unknown) {
const matched = Erreur.match(err, NumErreur);
// matched has type number | null
const matchedObj = Erreur.matchObj(err, { NumErreur, BoolErreur });
// matchedObj has type { kind: 'NumErreur', data: number } | { kind: 'BoolErreur', data: boolean } | null
}
```
#### Error `cause` and `erreurCause`
#### `warp` and `wrapAsync`
Wrap a function to make sure it either returns a value or throws an `Erreur` instance.
#### `resolve` and `resolveAsync`
Smae as `wrap` and `wrapAsync` but returns the `Erreur` instance instead of throwing it.

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