Skip to content

Commit

Permalink
feat(tinytype): support for serialising Error objects to JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-molak committed Aug 3, 2022
1 parent 11fc1a7 commit 50cfee6
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
22 changes: 22 additions & 0 deletions spec/TinyType.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,20 @@ describe('TinyType', () => {
expect(parameters.toJSON()).to.deep.equal(['apples', 'bananas', 'cucumbers']);
});

it(`should serialise an Error as its stack trace`, () => {
class CustomError extends TinyTypeOf<Error>() {
}

const error = thrown(new Error('example error'))

const customError = new CustomError(error);

expect(customError.toJSON()).to.deep.equal({
message: 'example error',
stack: error.stack,
});
});

it('should serialise a plain-old JavaScript object with nested complex types recursively', () => {
interface NotesType {
authCredentials: {
Expand Down Expand Up @@ -432,3 +446,11 @@ describe('TinyType', () => {
});
});
});

function thrown<T>(throwable: T): T {
try {
throw throwable;
} catch (error) {
return error as T;
}
}
10 changes: 10 additions & 0 deletions src/TinyType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ function toJSON(value: any): JSONObject | NonNullJSONPrimitive {
return toJSON(Array.from(value));
case value && isRecord(value):
return recordToJSON(value);
case value && value instanceof Error:
return errorToJSON(value);
case isSerialisablePrimitive(value):
return value;
default:
Expand All @@ -170,6 +172,14 @@ function recordToJSON(value: Record<any, any>): JSONObject {
return Object.fromEntries(serialised);
}

function errorToJSON(value: Error): JSONObject {
return Object.getOwnPropertyNames(value)
.reduce((serialised, key) => {
serialised[key] = toJSON(value[key])
return serialised;
}, { }) as JSONObject;
}

function isSerialisableNumber(value: unknown): value is number {
return typeof value === 'number'
&& ! Number.isNaN(value)
Expand Down

0 comments on commit 50cfee6

Please sign in to comment.