This is a simple AOP-ish toolset that lets to wrap sync and async functions and class methods with hooks which let you:
- override onTry:
- function's input parameters
- function's this arg
- function itself (hook can conditionally do some extra wrapping)
- override onCatch, onFinally:
- function's result
- function's error to (re-)throw
- log, measure all of those mentioned above
It supports using as decorator, function wrapper or scope of anonymous function:
It supports typescript
It supports sync and async functions/methods
/// track.ts
export const hooks = new Hooks()
.add(callStack)
.add(measureDuration)
.add(ctx => {
console.log(`ℹ️ Action ${ctx.name} started...`)
return {
onFinally() {
if(ctx.funcOutcome.error)
console.log(`❌ Action ${ctx.name} failed with ${ctx.funcOutcome.error}. Took ${ctx.duration}ms to complete`)
else
console.log(`✅ Action ${ctx.name} succeed with result:${ctx.funcOutcome.result}. Took ${ctx.duration}ms to complete`)
// you can override either result or error here
// if you set ctx.funcOutcome.error = undefined - function will not throw error
datadog.histogram(
`action-${ctx.name}-duration`,
ctx.duration,
{ tags: ['action:' + ctx.name, 'callstack:' + ctx.getCallStack().map(c => c.name).join('/')] }
);
},
};
})
export const track = hooks.create()
// myClass.ts
class MyClass{
@track({name:'Hello world'})
//@hooks.decor({name:'Hello world'}) //alternative
async helloWorld(url:string)
{
await doing()
await somethingLongRunning(url)
return await andErroneous()
}
}
// myFunc.ts
export const myFunc = track({name: 'My function'}, (param1:number)=>{ //alternative: myFunc = hooks.wrap({name:'Hello world'}, (param1...)=>{...})
// doing something long running and risky
step1()
step2()
const res = track.scope({name:'important step 3'},()=>{
return step3(param1)
})
return res
})
See specs for examples