Last active
November 27, 2018 07:43
-
-
Save swashcap/c4ab87722ab29a3597365fa741b83cbd to your computer and use it in GitHub Desktop.
Exploring custom error creation with TypeScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import assert from 'assert'; | |
interface CreateErrorOptions { | |
/** Additional error data */ | |
data?: string; | |
/** Whether clients should interpret error as fatal */ | |
fatal: boolean; | |
/** Error's PascalCase name */ | |
name: string; | |
/** HTTP status code */ | |
statusCode: number; | |
} | |
const createError = ({ | |
data, | |
fatal = true, | |
name, | |
statusCode, | |
}: CreateErrorOptions) => { | |
class AppError extends Error { | |
data?: string; | |
fatal: boolean; | |
statusCode: number; | |
constructor(error?: string | Error) { | |
if (typeof error === 'string') { | |
super(error); | |
} else if (error instanceof Error) { | |
super(error.message); | |
Object.assign(this, error); | |
} else { | |
super(); | |
} | |
Error.captureStackTrace(this, AppError); | |
if (data) { | |
this.data = data; | |
} | |
this.fatal = fatal; | |
this.name = name; | |
this.statusCode = statusCode; | |
} | |
} | |
return AppError; | |
}; | |
const MyError = createError({ | |
fatal: false, | |
name: 'MyError', | |
statusCode: 500, | |
}); | |
const errorFromString = new MyError('wow'); | |
assert.equal(errorFromString.message, 'wow'); | |
assert.equal(errorFromString.statusCode, 500); | |
assert.equal(errorFromString.fatal, false); | |
assert.equal(errorFromString.name, 'MyError'); | |
const originalError: any = new Error('oh my'); | |
originalError._secret = 'secret'; | |
const errorFromError: any = new MyError(originalError); | |
assert.equal(errorFromError.message, 'oh my'); | |
assert.equal(errorFromError.statusCode, 500); | |
assert.equal(errorFromError.fatal, false); | |
assert.equal(errorFromError.name, 'MyError'); | |
assert.equal(errorFromError._secret, 'secret'); | |
try { | |
const thrower = () => { | |
throw new MyError(); | |
}; | |
thrower(); | |
} catch (e) { | |
assert(/^\s+at thrower/m.test(e.stack)); | |
assert(!/^\s+at new MyError/m.test(e.stack)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment