Extendable javascript errors
After extending javascript Error
class in every single project and copying
allways different bad snippets from stackoverflow, i wanted to have a good
error base that i can reuse in different javascript/typescript projects.
This library tries to provide good simple base for javascript errors.
npm install --save errorjs
ErrorJS has a list of predefined errors, that you can reuse while devloping a service.
import {
NotImplementedError,
InternalError,
NotFoundError,
UnauthorizedError,
ConnectionError,
ValidationError,
ConflictError,
LogicalError
} from 'errorjs';
throw new NotImplementedError('some_feature_not_implemented');
throw new InternalError('something_internally');
throw new NotFoundError('something_was_not_found');
throw new UnauthorizedError('access_was_unauthroized');
throw new ConnectionError('error_with_connection_to_server');
throw new ValidationError('error_validating_resource');
throw new ConflictError('some_conflict');
throw new LogicalError('some_logic_error');
Every error must have error code provided, which should uniquely identify an error
import {ConflictError} from 'errorjs';
throw new ConflictError(); // <-- invalid since no error code is provided
throw new ConflictError('some_error_code'); // <-- good, since error code is provided
Additional context can be passed when creating an error
Simple error context
import {ConflictError} from 'errorjs';
throw new ConflictError('some_error_code', {some: 'context'});
Error class with predefined error context
const ConflictWithContext = ConflictError.withContext({some: 'context'});
throw new ConflictWithContext('some_error_code', {some: 'othercontext'});
Error factory with predefined error context
import {errors} from 'errorjs';
const contextErrors = errors.withContext({userId: '<some_user_id>'});
const error = new contextErrors.ConflictError('user_exists', {errorId: '<some_error_id>'});
error.context // {userId: '<some_user_id>', errorId: '<some_error_id>'}
Child errors can be passed to an error to encapsulate errors
import {ConflictError} from 'errorjs';
const baseError = new Error('some base error');
const baseError2 = new Error('some other error');
throw new ConflictError('some_error_code', baseError, baseError2);
Error constructor accepts variable number of arguments. This enable to pass multiple context objects to error.
import {ValidationError} from 'errorjs';
const baseError = new Error('some error has happend');
throw new ValidationError('some_error_code', baseError, {some: 'context'}, {some: 'other_context'});
ErrorJS is tightly integrated with typescript and provides type information.
import {errors} from 'errorjs';
errors.NotImplemented // <--- autocomplete here
new errors.NotFoundError( /* autocomplete here */ );
Error factory can be extended with new errors classes and base error can be redefined.
import {ExtendedErrorFactory} from 'errorjs';
class MyVeryBadErrorFactory extends ExtendedErrorFactory {
BaseError = class BaseError extends this.BaseError {
isVeryBadError = true;
get isUserError() {
return this.context.userID;
}
};
MyError = this.defineErrorClass(
class MyError extends this.BaseError {
meta = {httpCode: 500};
}
);
}
const factory = new MyErrorFactory();
const error = factory.NotFoundError('some_error', {userID: '123-123'});
error.isVeryBadError // <-- extended functionality here
throw new factory.MyError('some_error_code');
import {ExtendedErrorFactory} from 'errorjs';
class MyErrorFactory extends ExtendedErrorFactory {
BaseError = class MyBaseError extends this.BaseError {
scope = 'global';
get isUserError() {
return this.context.userId;
}
};
TransactionError = this.defineErrorClass(
class TransactionError extends this.ConflictError {
scope = 'transaction';
get userMessage() {
return `{${this.scope}} ${super.userMessage}`;
}
}
);
}
const errorFactory = new MyErrorFactory();
const userErrors = factory.withContext({userId: '<some_user_id>'});
throw new userErrors.TransactionError('transaction_not_found', 'transaction was not found', {
id: '<transaction_id>'
});
const {ExtendedErrorFactory} = require('errorjs');
class MyErrorFactory extends ExtendedErrorFactory {
constructor(...args) {
super(...args);
this.BaseError = class MyBaseError extends this.BaseError {
scope = 'global';
get isUserError() {
return this.context.userId;
}
};
this.TransactionError = this.defineErrorClass(
class TransactionError extends this.ConflictError {
get scope() {
return 'transaction';
}
get userMessage() {
return `{${this.scope}} ${super.userMessage}`;
}
}
);
}
}
const errorFactory = new MyErrorFactory();
const userErrors = factory.withContext({userId: '<some_user_id>'});
throw new userErrors.TransactionError('transaction_not_found', 'transaction was not found', {
id: '<transaction_id>'
});
npm t
: Run test suitenpm start
: Runs npm run build
in watch modenpm run test:watch
: Run test suite in interactive watch modenpm run test:prod
: Run linting and generate coveragenpm run build
: Generage bundles and typings, create docsnpm run lint
: Lints codenpm run commit
: Commit using conventional commit style (husky will tell you to use it if you haven't :wink:)Made with :heart: by @offlinehacker
Generated using TypeDoc