Skip to content

Commit

Permalink
Initial proposal
Browse files Browse the repository at this point in the history
  • Loading branch information
nephix committed Feb 12, 2020
1 parent 732ef28 commit b7a94fc
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 0 deletions.
26 changes: 26 additions & 0 deletions raiden-ts/src/utils/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export type ErrorDetail = { [key: string]: string };

export default abstract class RaidenError extends Error {
code: string;
details?: ErrorDetail[];

constructor(message: string, detail?: ErrorDetail[] | ErrorDetail) {
super(message || 'General Error');
this.name = 'RaidenError';
this.code = this.getCode(message);

if (detail) {
this.details = Array.isArray(detail) ? detail : [detail];
}
}

addDetail(detail: ErrorDetail) {
if (this.details) {
this.details.push(detail);
} else {
this.details = [detail];
}
}

abstract getCode(message: string): string;
}
78 changes: 78 additions & 0 deletions raiden-ts/tests/unit/error.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { isError } from 'util';

import RaidenError, { ErrorDetail } from '../../src/utils/error';

enum MyCustomErrorCodes {
TEST = 'Developer-friendly description',
}

class MyCustomError extends RaidenError {
constructor(message: MyCustomErrorCodes, detail?: ErrorDetail) {
super(message, detail);
this.name = 'MyCustomError';
}

getCode(message: string): string {
return (
Object.keys(MyCustomErrorCodes).find(code => Object(MyCustomErrorCodes)[code] === message) ??
'GENERAL_ERROR'
);
}
}

describe('Test custom error', () => {
test('MyCustomError is instance of its custom class', () => {
try {
throw new MyCustomError(MyCustomErrorCodes.TEST);
} catch (err) {
expect(err).toBeInstanceOf(MyCustomError);
expect(err.name).toEqual('MyCustomError');
}
});

test('MyCustomError is an instance of Error', () => {
try {
throw new MyCustomError(MyCustomErrorCodes.TEST);
} catch (err) {
expect(err instanceof Error).toBeTruthy();
expect(isError(err)).toBeTruthy();
}
});

test('Has stack trace w/ class name and developer-friendly message', () => {
try {
function doSomething() {
throw new MyCustomError(MyCustomErrorCodes.TEST);
}
doSomething();
} catch (err) {
// Stack trace exists
expect(err.stack).toBeDefined();

// Stack trace starts with the error message
expect(err.stack.split('\n').shift()).toEqual(
'MyCustomError: Developer-friendly description',
);

// Stack trace contains function where error was thrown
expect(err.stack.split('\n')[1]).toContain('doSomething');
}
});

test('End user "code" property is set', () => {
try {
throw new MyCustomError(MyCustomErrorCodes.TEST);
} catch (err) {
expect(err.code).toBeDefined();
expect(err.code).toEqual('TEST');
}
});

test('Details can be added and are shown in stack trace', () => {
try {
throw new MyCustomError(MyCustomErrorCodes.TEST, { foo: 'bar' });
} catch (err) {
expect(err.details).toEqual([{ foo: 'bar' }]);
}
});
});

0 comments on commit b7a94fc

Please sign in to comment.