Inspired by VError and written in TypeScript. Compatible with deno. Zero dependencies.
A BError
is just like a regular Error
with three added benefits:
When you create a BError
you can provide it with the error that caused it.
It doesn't need to be a BError
. Any Error
will work:
try {
throw new Error("Something went wrong")
} catch (e) {
throw new BError("Oops", e)
}
// will create an error with the message: `Oops: Something went wrong`
You can add some metadata to your errors to help with debugging:
const path = "/test"
try {
tryToOpenPath(path)
} catch (e) {
throw new BError("Could not open path", e, {path})
}
// will create an error with the message:
// `Could not open path: permission denied {path: "/test"}`
The metadata is kept in the chain, the final error will contain all the metadata of the errors that caused it. If two errors send the same metadata property, the last one will override the first one.
If you want to send metadata but you don't have an error that you just caught you can
pass undefined
or null
to the constructor: new BError("Oops", undefined, {foo: 42})
BError comes with a log
function that makes it easy and short to log the error.
// will log the error using console.error()
new BError("Something went wrong").log()
BError is meant to be extended to integrate your own logger.
Just extend the BError
class and override the log
function to do whatever you want.
Example with winston:
import {BError} from "berror"
import {createLogger, transports} from 'winston'
const logger = createLogger({
level: 'debug',
transports: [
new transports.Console()
]
})
export class MyError extends BError {
public log(level: string) {
if (level === "error") {
logger.error(this.message, this.metadata)
} else {
logger.info(this.message, this.metadata)
}
}
}