Step 1 of 5 · Reading · ~3 min
Learn
Error Handling
Custom Error Classes
The built-in errors tell you what kind of mistake happened in general terms. Your own program has failures of its own: a card was declined, a user was not found. This lesson shows how to give those their own types so callers can react to them without parsing message text. By the end you can write an error class, build a small hierarchy, and wrap a low-level error while keeping the original.
Why a class and not a message
Messages are for people and they change. A caller should test the type, and instanceof does that.
Extending Error
Four details matter here:
- In a subclass constructor you cannot touch
thisuntilsuper(...)has run. Writingthis.x = 1first throws aReferenceError. super(message)is what sets.messageand records the stack trace.nameis"Error"unless you change it, andString(err)and logged stack traces use it.new.target.name(orthis.constructor.name) reads the actual class name, so every subclass reports itself correctly without repeating the line.- Extra fields (
code,last4) are ordinary properties. Give the constructor the arguments that make sense to its callers and build the message inside it.
A hierarchy and instanceof
Make one base class for all your errors, and subclasses for the cases callers distinguish. Then instanceof works at every level:
Test the most specific class first, because a subclass instance also matches its parents.
Wrapping: keep the original cause
JSON.parse(text) turns JSON text into a value and throws a SyntaxError when the text is malformed. When a low-level error like that escapes, callers rarely want that. They want your type, but you should not lose the original:
Newer JavaScript accepts new Error(msg, { cause }) for this; the older engines your exercises run on do not, so you store it yourself. Naming the property cause keeps it compatible.
Serialising
JSON.stringify(new Error("x")) is "{}": message and stack are not enumerable, so they are skipped. A custom error stringifies only the fields you assigned (name, code, last4 above). If you send errors over the wire, build the object you want explicitly.
Common mistakes
- Using
thisbeforesuper(...). - Forgetting to set
name, so everything prints asError. - Branching on message text instead of the class.
- Catching the parent class before the subclass, so the subclass branch never runs.
- Wrapping an error and dropping the original, which removes the clue you needed.
- Putting
new Errorinstances inJSON.stringifyand expecting the message.
Your exercise
Define the classes that the rest of the starter already uses. Pay attention to the arguments the starter passes to each constructor, and to the status code each kind of error carries.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…