Type-Safe Catch Blocks
catch-unknown is a focused utility library designed to simplify the handling of `unknown` error types within JavaScript and TypeScript `catch` blocks. Following TypeScript 4.4's decision to default `catch` variables to `unknown`, developers are required to perform explicit type guarding or conversion. This library provides two primary functions: `isError`, which functions as a type guard to verify if a value conforms to the standard `Error` interface, and `asError`, which transforms any thrown value into an `Error`-like object, guaranteeing it possesses at least `name` and `message` properties. Currently at version `2.0.0`, the library emphasizes stability, minimal footprint, compiles to ES6 for broad compatibility, and has no runtime dependencies, ensuring a small package size and efficient error handling without introducing complex abstractions.
Common errors
-
Property 'message' does not exist on type 'unknown'.
cause Attempting to access properties (e.g., `.message`, `.name`) directly on a `catch` variable typed as `unknown` without prior type narrowing or conversion. This is the default behavior for `catch` variables in TypeScript 4.4 and newer when `useUnknownInCatchVariables` is active.fixUse `catch-unknown`'s `isError` type guard (`if (isError(err)) { ... }`) or convert the error using `asError(err)` before accessing properties (e.g., `asError(err).message`). Ensure your `tsconfig.json` has `useUnknownInCatchVariables` enabled. -
TypeError: (0, catch_unknown_1.asError) is not a function
cause This error typically indicates a CommonJS/ESM module interop issue where a named export is incorrectly imported as a default, or a bundler misinterprets the module format when transpiling.fixEnsure you are using named imports for `asError` and `isError`: `import { asError } from 'catch-unknown';`. If using CommonJS, correctly destructure the named export: `const { asError } = require('catch-unknown');`. -
Cannot find module 'catch-unknown' or its corresponding type declarations.
cause The package is not installed in the project, or TypeScript cannot locate its declaration files (`.d.ts`), which are essential for type checking.fixInstall the package via your package manager: `npm install catch-unknown` or `yarn add catch-unknown`. If the problem persists in a TypeScript project, verify your `tsconfig.json` `types` or `typeRoots` settings, although this is uncommon for well-maintained packages.
Warnings
- gotcha TypeScript versions 4.4 and above default `catch` block variables to `unknown` type when `useUnknownInCatchVariables` is enabled (implicitly by `strict` mode or explicitly). This change means you cannot directly access properties like `.message` or `.name` on a caught `err` without explicit type narrowing or conversion, leading to TypeScript errors.
Install
-
npm install catch-unknown -
yarn add catch-unknown -
pnpm add catch-unknown
Imports
- asError
const asError = require('catch-unknown').asError;import { asError } from 'catch-unknown'; - isError
const isError = require('catch-unknown').isError;import { isError } from 'catch-unknown';
Quickstart
import { asError } from 'catch-unknown';
// A dummy logger for demonstration purposes
const logger = {
warn: (message: string) => console.warn(`[WARN] ${message}`),
error: (message: string) => console.error(`[ERROR] ${message}`)
};
async function performRiskyOperation() {
return new Promise((resolve, reject) => {
// Simulate an error or non-Error throw
const rand = Math.random();
if (rand < 0.3) {
reject(new Error('Standard error occurred'));
} else if (rand < 0.6) {
reject('A simple string was thrown');
} else {
reject({ code: 500, detail: 'An unexpected object was thrown' });
}
});
}
async function runExample() {
try {
await performRiskyOperation();
console.log('Operation successful!');
} catch (err) {
// Use asError to safely log the error message regardless of what was thrown
const errorObject = asError(err);
logger.warn(`Operation failed: ${errorObject.message}`);
// Rethrow the original error if necessary
throw err;
}
}
runExample().catch(finalErr => {
logger.error(`Application level error caught: ${asError(finalErr).message}`);
});