I have been playing with custom errors and how it can help with monitoring AWS lambda based APIs.
The native Error of JavaScript is kinda meh. You can only set a message, which, I find, is not enough to determine an issue in production, i.e. ‘http request failed’. What I would love to know is some context, at least: url, headers, payload, response.
I have tried to stringify error context and attach to an error message, but it was difficult to read the logs and therefore didn't spark joy.
Ultimately, I would prefer not to look at the logs at all, the monitoring tool should tell me what's wrong and maybe even give a solution. Got better things to do, than debugging logs :)))
Error does not like serialisation.
try {
throw new Error("Something bad happened");
} catch (err) {
const serialised = JSON.stringify(err);
console.log(serialised);
}
outputs:
{}
Let's serialise the Error
So what we could do is to create an BaseError, which has a property reason.
export class BaseError extends Error {
public readonly reason: string;
constructor(reason: string) {
super(reason);
this.name = BaseError.name;
Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
this.reason = reason;
}
}
now when we run this:
try {
throw new BaseError("Something bad happened");
} catch (err) {
let serialised = JSON.stringify(err);
console.log(serialised);
}
we get
{"name":"BaseError","reason":"Something bad happened"}
Let's make a custom Error
So once we have a BaseError, we can create an purpose built error like that:
export class SuperHeroError extends BaseError {
public readonly superHeroName: string;
constructor(superHeroName: string) {
super(`superhero ${superHeroName} malfunctioned`);
this.name = SuperHeroError.name;
Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
this.superHeroName = superHeroName;
}
}
and when we run it:
try {
throw new SuperHeroError("Batman");
} catch (err) {
let serialised = JSON.stringify(err);
console.log(serialised);
}
we get this:
{"name":"SuperHeroError","reason":"superhero Batman malfunctioned","superHeroName":"Batman"}
AWS CloudWatch LogInsights report
Once we have some failure logs, we can write a query like this:
fields @timestamp as timestamp, name, reason
| sort @timestamp desc
| limit 100
and the result will be:
timestamp | name | reason |
---|---|---|
2020-07-23 12:59:30.716 | SuperHeroError | superhero Batman malfunctioned |
This is very basic error logging, in the real world you will need much more data in the logs, like sessionId, requestId etc. :)
Top comments (0)