Creating Error type
APIError factory creation
Overview
Extending globalThis.Error have multiple drawbacks :
- Matching on errors relies on 
instanceofwhich have some limitations (ex:iframe) - Can be verbose even for adding just one property
 
The @w5s/error package helps creating type safe errors :
- Easy declaration extending 
ErrorClass - Type safe matching on 
name - Discourage matching using 
instanceof 
Declaring a new type
import { ErrorClass } from '@w5s/error';
//           ┌─ ✓ PascalCase
//           │  ✓ Name + 'Error'
//           │                     ┌─ Extends from ErrorClass()
export class {{SomeError}} extends ErrorClass({ 
  errorName: '{{SomeError}}'; // <- Required
  // errorMessage: 'This is an error message', // <- Optional
})<{
  // ↓ Extra properties
  // myProperty: string;
}> {}
Example 1 : Basic
import { ErrorClass } from '@w5s/error';
export class BasicError extends ErrorClass({ 
  errorName: 'BasicError',
})<{}> {}
// Create an instance with : 
//
// new BasicError();
// new BasicError({ message: 'Custom message' });
Example 2 : Advanced with extra properties
import { ErrorClass } from '@w5s/error';
export class AdvancedError extends ErrorClass({ 
  errorName: 'AdvancedError',
  errorMessage: 'Advanced error occurred',
})<{
  customProperty: string;
}> {}
// Create an instance with : 
//
// new AdvancedError({
//   message: 'This is a message',
//   customProperty: 'custom',
//   cause: new TypeError('This is the cause')
// })
Matching errors
The recommended way to match on errors created with ErrorClass is to use a switch / case on the error name
class FooError extends ErrorClass({ errorName: 'FooError' })<{ fooProperty: string; }> {};
class BarError extends ErrorClass({ errorName: 'BarError' })<{ barProperty: number; }> {};
function parse(): Result<string, FooError | BarError> {
  //...
}
function program() {
  const result = parse();
  if (Result.isError(result)) {
    switch (result.name) {
      case FooError.errorName: { 
        console.log('FooError:', error.fooProperty);
        break;
      }
      case BarError.errorName: { 
        console.log('BarError:', error.barProperty);
        break;
      }
      default: assertNever(result.name);
    }
  }
}
Caused / Specializing error
CustomError can be used to create specific errors with a cause property that is useful to keep track of the chain of errors.
class CauseError extends ErrorClass({ errorName: 'CauseError' })<{}> {};
try {
  // ...
  // return Result.Ok();
} catch (error) {
  return Result.Error(new CauseError({
    message: 'This is a better error',
    cause: error, // <- The cause property can be any type but preferably an error object.
  }));
}