@tunebond/halt
Standard Error Handling in TypeScript
Installation
pnpm add @tunebond/halt
yarn add @tunebond/halt
npm i @tunebond/halt
Overview
You specify errors with a code
which is an integer, and a note
which
is the message generating function.
type WithName = {
name: string
}
type WithType = WithName & {
type: string
}
const base = {
invalid_form: {
code: 3,
note: ({ name }: WithName) => `Form '${name}' is not valid`,
},
invalid_type: {
code: 2,
note: ({ name, type }: WithType) =>
`Value '${name}' is not '${type}' type`,
},
missing_property: {
code: 1,
note: ({ name }: WithName) => `Property '${name}' missing`,
},
}
The default integer stringifier for the code
is like this:
export const makeCode = (code: number) =>
code.toString(16).padStart(4, '0').toUpperCase()
So it will print 000F
for code number 16, etc.
You can also format the text:
export const makeText = (host: string, code: string, note: string) =>
`${host} [${code}] ${note}`
So an error message might be like (this is defined for the
@tunebond/halt
namespace, but you would have your own namespace):
Halt: @tunebond/halt [0003] Form 'string' is not valid
... stack trace
This is nice because it gives you slightly better context as to what
library or app is throwing the error (using the host
property), and
the codes make it easier to search the web for the error (if your
library/app potentially becomes popular).
Finally, you define the halt
function which you use in your library or
app, and export it out. A full example of that is next.
Example
Configure the Errors
Say we put these in ./errors
:
import Halt, { Link } from '@tunebond/halt'
import { convertIntegerToId } from '../utils/id'
import { permute8 } from '../utils/prng'
type WithName = {
name: string
}
type WithType = WithName & {
type: string
}
const base = {
invalid_form: {
code: 3,
note: ({ name }: WithName) => `Form '${name}' is not valid`,
},
invalid_type: {
code: 2,
note: ({ name, type }: WithType) =>
`Value '${name}' is not '${type}' type`,
},
missing_property: {
code: 1,
note: ({ name }: WithName) => `Property '${name}' missing`,
},
}
type Base = typeof base
type Name = keyof Base
// you don't have to override this, but you can if you want.
// it defaults to:
// `code.toString(16).padStart(4, '0').toUpperCase()`
// which means it assumes less than 16^4 = 65536
// 65k errors per namespace, which is plenty.
const code = (code: number) =>
convertIntegerToId(permute8(code)).padStart(4, 'M')
export default function halt(form: Name, link: Link<Base, Name>) {
return new Halt({ base, form, link, code })
}
Throw the Errors
Now somewhere else in the code:
import { halt } from './errors'
try {
throw halt('invalid_type', { name: 'foo', type: 'array' })
} catch (e) {
console.log(e.toJSON()) // perfect for REST APIs
}
License
MIT
TuneBond
This is being developed by the folks at TuneBond, a California-based project for helping humanity master information and computation. TuneBond started off in the winter of 2008 as a spark of an idea, to forming a company 10 years later in the winter of 2018, to a seed of a project just beginning its development phases. It is entirely bootstrapped by working full time and running Etsy and Amazon shops. Also find us on Facebook, Twitter, and LinkedIn. Check out our other GitHub projects as well!