Strategy for `name` property given uglification?
ckknight opened this issue · comments
Given that name is determined via this.constructor.name
, if one were to minify their code and mangle the names, this could lead to new MyCustomError().name === 'e'
.
The short answer
I hadn't really considered this. I originally built this library with the only intention of using it in Bluebird's .catch
predicate filters (e.g. .catch(NotFoundError, (err) => { ... })
).
This isn't ideal, but if you're using uglifyjs2, there are a few options available that might solve this for you quickly:
keep_fnames
/--keep-fnames
disables mangling of function names (easier, but obviously results in less minification)reserved
allows you to provide a list of identifiers that should not be mangled (harder to maintain)
The long answer
I've given a some thought to this library lately. I consider it to be a hack, and I'm not really a fan of hacks. Given the number of ways that it can break or fail to work as intended (uglifying, use with typescript, issues with different module bundlers, cross-environment issues, changes to babel, etc.), I would almost recommend not using it.
A much simpler pattern that involves zero hacks could look something like this:
const notFound = 'NotFoundError';
function notFoundError(err) {
err.name = notFound;
return err;
}
function isNotFoundError(err) {
return err.name === notFound;
}
try {
throw notFoundError(new Error('message'));
} catch(err) {
if (isNotFoundError(err)) {
// handle
} else {
// handle other
}
}
This should still capture the correct stack trace and message, while preserving the error name. You could also create other decorator functions to add additional info/properties to the error.
Added a link to this issue in the readme. Closing for now.