A custom error class gives domain failures a clear name and extra data.

custom error A custom error class extends `Error` and can carry fields that make recovery easier.

Custom Error Classes

inputName
custom.ts
Replay: real traced execution (multi-file project)
class ValidationError extends Error {
    field: string;

    constructor(field: string, message: string) {
        super(message);
        this.field = field;
    }
}

function requireName(name: string): string {
    if (name.length === 0) {
        throw new ValidationError("name", "required");
    }
    return name.toUpperCase();
}

const inputName: string = "ada";

try {
    const normalized: string = requireName(inputName);
    console.log(`name=${normalized}`);
} catch (error) {
    if (error instanceof ValidationError) {
        console.log(`${error.field}=invalid`);
    }
}
class ValidationError extends Error {
    field: string;

    constructor(field: string, message: string) {
        super(message);
        this.field = field;
    }
}

function requireName(name: string): string {
    if (name.length === 0) {
        throw new ValidationError("name", "required");
    }
    return name.toUpperCase();
}

const inputName: string = "";

try {
    const normalized: string = requireName(inputName);
    console.log(`name=${normalized}`);
} catch (error) {
    if (error instanceof ValidationError) {
        console.log(`${error.field}=invalid`);
    }
}
class ValidationError extends Error {
    field: string;

    constructor(field: string, message: string) {
        super(message);
        this.field = field;
    }
}

function requireName(name: string): string {
    if (name.length === 0) {
        throw new ValidationError("name", "required");
    }
    return name.toUpperCase();
}

const inputName: string = "linus";

try {
    const normalized: string = requireName(inputName);
    console.log(`name=${normalized}`);
} catch (error) {
    if (error instanceof ValidationError) {
        console.log(`${error.field}=invalid`);
    }
}
  1. inputName ← ada

    14    return name.toUpperCase();15}1617const inputName→ ada: string = "ada";  //@inputName="", "linus"
  2. //@inputName="", "linus" try

    17const inputName: string = "ada";  //@inputName="", "linus"1819try {20    const normalized: string = requireName(inputNameada);21    console.log(`name=${normalized}`);
  3. function requireName(name: string): string

    7    }8}910function requireName(nameada: string): string {11    if (name.length === 0) {12        throw new ValidationError("name", "required");13    }14    return nameada.toUpperCase();15}
  4. normalized ← ADA

    19try {20    const normalized→ ADA: string = requireName(inputNameada);21    console.log(`name=${normalizedADA}`);22} catch (error) {
    outputname=ADA
  1. inputName ← (empty)

    14    return name.toUpperCase();15}1617const inputName→ (empty): string = "";
  2. try

    17const inputName: string = "";1819try {20    const normalized: string = requireName(inputName(empty));21    console.log(`name=${normalized}`);
  3. function requireName(name: string): string

    7    }8}910function requireName(name(empty): string): string {11    if (name.length === 0) {
  4. if (name.length === 0)

    10function requireName(name: string): string {11    if (name.length0 === 0) {12        throw new ValidationError("name", "required");13    }
  5. this.field ← name

    4constructor(field: string, message: string) {5    super(messagerequired);6    this.field = fieldname;7}
    values this stepnamethis.field
  6. if (error instanceof ValidationError)

    21    console.log(`name=${normalized}`);22} catch (error) {23    if (errorError: required instanceof ValidationErrorclass ValidationError extends Error {
        constructor(field, message) {
            console.log("@@TRACE|custom.ts|-1|BEFORE|4.50-5.24:\n        super(message);|" + ("5.15-5.22:message:" + String(message).length + ":" + String(message)) + "@@END");
            super(message);
            console.log("@@TRACE|custom.ts|-1|AFTER|4.50-5.24:\n        super(message);|" + ("5.15-5.22:message:" + String(message).length + ":" + String(message)) + "@@END");
            console.log("@@TRACE|custom.ts|-1|BEFORE|5.24-6.28:\n        this.field = field;|" + ("6.21-6.27: field:" + String(field).length + ":" + String(field)) + "@@END");
            this.field = field;
            console.log("@@TRACE|custom.ts|-1|AFTER|5.24-6.28:\n        this.field = field;|" + ("5.24-6.19:\n        this.field:" + String(this.field).length + ":" + String(this.field) + ", " + "6.21-6.27: field:" + String(field).length + ":" + String(field)) + "@@END");
        }
    }) {24        console.log(`${error.fieldname}=invalid`);25    }
    outputname=invalid
  1. inputName ← linus

    14    return name.toUpperCase();15}1617const inputName→ linus: string = "linus";
  2. try

    17const inputName: string = "linus";1819try {20    const normalized: string = requireName(inputNamelinus);21    console.log(`name=${normalized}`);
  3. function requireName(name: string): string

    7    }8}910function requireName(namelinus: string): string {11    if (name.length === 0) {12        throw new ValidationError("name", "required");13    }14    return namelinus.toUpperCase();15}
  4. normalized ← LINUS

    19try {20    const normalized→ LINUS: string = requireName(inputNamelinus);21    console.log(`name=${normalizedLINUS}`);22} catch (error) {
    outputname=LINUS