
Marcus Nguyen
Software Engineer
In real-world apps, errors can come from:
We want to:
Use custom classes to differentiate known and unknown errors.
class DefinedError extends Error {
  code: string;
  constructor(message: string, code: string = 'DEFINED_ERROR') {
    super(message);
    this.name = 'DefinedError';
    this.code = code;
  }
}
class UnexpectedError extends Error {
  constructor(message: string = 'An unexpected error occurred') {
    super(message);
    this.name = 'UnexpectedError';
  }
}
Hereβs how you can throw and wrap errors based on what goes wrong:
async function riskyOperation(): Promise<string> {
  try {
    // Simulate known failure
    const shouldFail = Math.random() > 0.5;
    if (shouldFail) {
      throw new DefinedError('Invalid operation: Something went wrong.', 'INVALID_ACTION');
    }
    // Simulate success
    return 'Success!';
  } catch (error) {
    if (error instanceof DefinedError) {
      throw error; // Forward known error
    }
    // Wrap unexpected issues
    throw new UnexpectedError(error instanceof Error ? error.message : String(error));
  }
}
try {
  const result = await riskyOperation();
  console.log('β
 Result:', result);
} catch (error) {
  if (error instanceof DefinedError) {
    console.warn(`[Handled] ${error.code}: ${error.message}`);
    // Show user-friendly message
  } else if (error instanceof UnexpectedError) {
    console.error(`[Unexpected] ${error.message}`);
    // Report to Sentry or monitoring tools
  } else {
    console.error('[Unknown error type]', error);
  }
}
If you want to centralize your logic:
function handleError(error: unknown) {
  if (error instanceof DefinedError) {
    console.warn(`[Handled] ${error.code}: ${error.message}`);
  } else if (error instanceof UnexpectedError) {
    console.error(`[Unexpected] ${error.message}`);
  } else {
    console.error('[Unknown error]', error);
  }
}
Then just:
try {
  await riskyOperation();
} catch (err) {
  handleError(err);
}
β
 Benefits of This Pattern
With just a few lines of setup, youβve now got: