DeesseJS Errors

Type Checking

Use the is() function to check error types and inheritance relationships in @deessejs/errors.

The is() function is your primary tool for checking what kind of error you're dealing with. It works with @deessejs/errors instances, native JavaScript errors, and respects the full inheritance hierarchy.

Basic Type Checking

Pass an error and an error type to is() to check if the error is an instance of that type:

basic.ts
import { error, is } from '@deessejs/errors';

const AppError = error({ name: 'AppError' });
const ValidationError = error({
  name: 'ValidationError',
  inherits: AppError,
});

const err = ValidationError({ field: 'email' });

console.log(is(err, ValidationError)); // true
console.log(is(err, AppError)); // true (through inheritance)

The function returns true if the error matches the type directly or inherits from it.

Using is() in Catch Blocks

The most common use case is inside catch blocks where you need to handle different error types:

catch-block.ts
import { error, raise, is } from '@deessejs/errors';

const AppError = error({ name: 'AppError' });
const ValidationError = error({
  name: 'ValidationError',
  inherits: AppError,
});
const NetworkError = error({
  name: 'NetworkError',
  inherits: AppError,
});

function handleError(err: unknown) {
  if (is(err, ValidationError)) {
    console.log(`Validation failed: ${err.fields?.field}`);
  } else if (is(err, NetworkError)) {
    console.log(`Network error: ${err.fields?.endpoint}`);
  } else if (is(err, AppError)) {
    console.log(`General app error: ${err.message}`);
  }
}

TypeScript narrows the type inside each branch when using is(), giving you access to the correct fields.

Working with Native Errors

The is() function also works with native JavaScript errors:

native.ts
import { error, is } from '@deessejs/errors';

const AppError = error({ name: 'AppError' });

try {
  JSON.parse('invalid json');
} catch (err) {
  if (is(err, SyntaxError)) {
    console.log('JSON parsing failed');
  } else if (is(err, AppError)) {
    console.log('Application error');
  }
}

This lets you mix @deessejs/errors with standard JavaScript error handling seamlessly.

Type Narrowing

When is() returns true, TypeScript knows the error is of that specific type. This enables type-safe access to fields:

type-safety.ts
import { error, is } from '@deessejs/errors';

const ValidationError = error<{ field: string; reason: string }>({
  name: 'ValidationError',
});

function processError(err: unknown) {
  if (is(err, ValidationError)) {
    // TypeScript knows err is ValidationError
    // So we can safely access fields
    console.log(`Field: ${err.fields.field}`);
    console.log(`Reason: ${err.fields.reason}`);
  }
}

Without the is() check, TypeScript would report an error because err is unknown.

Multiple Type Checks

You can check for multiple types in sequence:

multiple.ts
import { error, is } from '@deessejs/errors';

const AppError = error({ name: 'AppError' });
const ValidationError = error({
  name: 'ValidationError',
  inherits: AppError,
});
const NetworkError = error({
  name: 'NetworkError',
  inherits: AppError,
});

function categorize(err: unknown): string {
  if (is(err, NetworkError)) return 'network';
  if (is(err, ValidationError)) return 'validation';
  if (is(err, AppError)) return 'app';
  return 'unknown';
}

Order your checks from most specific to least specific to ensure the correct handler is triggered.

Why Not Use instanceof?

Native JavaScript instanceof doesn't work with @deessejs/errors errors because they're created with a factory function rather than a class. The is() function bridges this gap and adds support for inheritance checking.

comparison.ts
import { error, is } from '@deessejs/errors';

const AppError = error({ name: 'AppError' });
const ValidationError = error({
  name: 'ValidationError',
  inherits: AppError,
});

const err = ValidationError({});

// This works
console.log(is(err, ValidationError)); // true
console.log(is(err, AppError)); // true

// This doesn't work for @deessejs/errors
console.log(err instanceof ValidationError); // false

Always use is() instead of instanceof when working with @deessejs/errors errors.

See Also

On this page