Error handling

Don't get me wrong: Your code _will_ break, so let's just aggressively prepare for handling errors and exceptions rather than pulling out the ukulele and singing Kumbaya.
Since we are using TypeScript, which is a superset of JavaScript, I'll just take a moment to note that in this language an Error and an Exception are for all intents and purposes the same. If you use another language, feel free to translate the advice "generally" back into your context.
If you are a JavaScript/TypeScript/Node developer, you are most certainly aware of throw new Error("omg it broke again! :/") — Throwing an error with an optional message.
In most languages, there seems to be a more well-established convention to create special errors or exceptions that we can raise when something goes south. I have no hard numbers on this, but I am happy to support that we should indeed do the same for our applications!
A pattern I am using is the one we can see exemplified here:
code/Analytics/SlotAnalytics/src/application/errors/MissingDataFieldsError.ts
1
import { MikroLog } from "mikrolog";
2
​
3
/**
4
* @description Used when data input is missing required fields.
5
*/
6
export class MissingDataFieldsError extends Error {
7
constructor() {
8
super();
9
this.name = "MissingDataFieldsError";
10
const message = `Missing one or more required fields!`;
11
this.message = message;
12
​
13
const logger = MikroLog.start();
14
logger.error(message);
15
}
16
}
This basic variant can be copied as a foundation for other unique errors as well. I've kept them in the same file ({folders}/application/errors/errors.ts) as well as distinct files in that sort of structure. I have no heavy opinion and I've found that as long as we keep them in a clear application-level location it's all workable regardless.
For certain types of errors you may want to take in input, like so:
constructor(inputMessage: string) {
super(inputMessage);
this.name = 'DemoError';
const message = `Something went wrong: ${inputMessage}`;
this.message = message;
​
const logger = MikroLog.start();
logger.error(message);
}
Using custom errors is something that is going to help you significantly as you'll begin to operate your solution.