{"_id":"typescript-errors","_rev":"27-19adcb62bea0fc97f22daf1a818361b9","name":"typescript-errors","dist-tags":{"latest":"1.1.1"},"versions":{"0.9.2":{"name":"typescript-errors","version":"0.9.2","keywords":[],"author":{"name":"bo@interrobang.consulting"},"license":"MIT","_id":"typescript-errors@0.9.2","maintainers":[{"name":"robert-bo-davis","email":"bo@interrobang.consulting"}],"homepage":"https://github.com/interrobangc/typescript-errors","bugs":{"url":"https://github.com/interrobangc/typescript-errors/issues"},"dist":{"shasum":"2f4c85feaa7e649341088dc06c5e3a706e3db089","tarball":"https://registry.npmjs.org/typescript-errors/-/typescript-errors-0.9.2.tgz","fileCount":15,"integrity":"sha512-OfQxpuKnSgXwKXFWvOGnyIhd490gQBtftrLQpBokC4AVTu60V9BScyCLYiqwl9ghMoLkTBz7x7zxJV4Jx+D/Xw==","signatures":[{"sig":"MEUCIDeT39lcgHyooLiKOH+UIyMUsd8F+rAMueCg8gIjfjhXAiEA/RZSkOOAJDEJONt2VtyLF8TnPlbhm3a1IakP9cYbESM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":29614},"main":"dist/index.js","type":"module","_from":"file:typescript-errors-0.9.2.tgz","types":"dist/index.d.ts","scripts":{"lint":"run-p lint:prettier lint:eslint","test":"run-p lint:fix typecheck test:unit","build":"tsc","lint:fix":"run-p lint:prettier:fix lint:eslint:fix","test:unit":"vitest run --coverage","typecheck":"tsc --noEmit","npmPublish":"run-s test build npmPublish:run","lint:eslint":"eslint .","lint:prettier":"prettier . --check","npmPublish:run":"pnpm publish --access public","lint:eslint:fix":"eslint . --fix","test:unit:watch":"vitest","test:integration":"vitest run --test-timeout=120000 --config ./vitest.integration.ts","lint:prettier:fix":"prettier . --write"},"_npmUser":{"name":"robert-bo-davis","email":"bo@interrobang.consulting"},"_resolved":"/private/var/folders/cf/8rnx8bz17xbgc2v70hjzb04w0000gn/T/56c4bf9721f0f72ab013f3d95b92baf7/typescript-errors-0.9.2.tgz","_integrity":"sha512-OfQxpuKnSgXwKXFWvOGnyIhd490gQBtftrLQpBokC4AVTu60V9BScyCLYiqwl9ghMoLkTBz7x7zxJV4Jx+D/Xw==","repository":{"url":"git+https://github.com/interrobangc/typescript-errors.git","type":"git"},"_npmVersion":"10.9.0","description":"Minimal type safe error handling for TypeScript","directories":{},"_nodeVersion":"22.12.0","_hasShrinkwrap":false,"devDependencies":{"jiti":"^2.4.2","eslint":"^9.19.0","vitest":"^3.0.4","prettier":"^3.4.2","@eslint/js":"^9.19.0","typescript":"^5.7.3","@types/node":"^22.12.0","npm-run-all":"^4.1.5","@eslint/compat":"^1.2.6","typescript-eslint":"^8.22.0","@vitest/coverage-v8":"^3.0.4","eslint-plugin-import":"^2.31.0","eslint-plugin-sonarjs":"^3.0.1","eslint-config-prettier":"^10.0.1","@types/eslint-config-prettier":"^6.11.3"},"_npmOperationalInternal":{"tmp":"tmp/typescript-errors_0.9.2_1738427833458_0.4738013811836528","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"typescript-errors","version":"1.0.0","keywords":[],"author":{"name":"bo@interrobang.consulting"},"license":"MIT","_id":"typescript-errors@1.0.0","maintainers":[{"name":"robert-bo-davis","email":"bo@interrobang.consulting"}],"homepage":"https://github.com/interrobangc/typescript-errors","bugs":{"url":"https://github.com/interrobangc/typescript-errors/issues"},"dist":{"shasum":"8f9f2faeda72f7a7e520c1d0dd0bcd2bcea57076","tarball":"https://registry.npmjs.org/typescript-errors/-/typescript-errors-1.0.0.tgz","fileCount":12,"integrity":"sha512-PJwc8PufGMkiEdVFU7ts9BZmwH4eo53C9FrXENVL9arlM/aNvVhtt9gEGHcU6Htj76z7YcuOXtCXB7GgU2Nmcw==","signatures":[{"sig":"MEUCICAAsiicLB0nlW7k9A4jUwXxwWGEzDxTjlKvvX3wxT3uAiEAxmxnhqfSCD/5uNxfgFcfve+heFoSRsjqlfW30vcumu0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23189},"main":"dist/index.js","type":"module","_from":"file:typescript-errors-1.0.0.tgz","types":"dist/index.d.ts","scripts":{"lint":"run-p lint:prettier lint:eslint","test":"run-p lint:fix typecheck test:unit","build":"tsc","lint:fix":"run-p lint:prettier:fix lint:eslint:fix","test:unit":"vitest run --coverage","typecheck":"tsc --noEmit --project tsconfig.test.json","npmPublish":"run-s test build npmPublish:run","lint:eslint":"eslint .","lint:prettier":"prettier . --check","npmPublish:run":"pnpm publish --access public","lint:eslint:fix":"eslint . --fix","test:unit:watch":"vitest","test:integration":"vitest run --test-timeout=120000 --config ./vitest.integration.ts","lint:prettier:fix":"prettier . --write"},"_npmUser":{"name":"robert-bo-davis","email":"bo@interrobang.consulting"},"_resolved":"/private/var/folders/cf/8rnx8bz17xbgc2v70hjzb04w0000gn/T/9db6f7a6c4303196649a7754ee16e8e4/typescript-errors-1.0.0.tgz","_integrity":"sha512-PJwc8PufGMkiEdVFU7ts9BZmwH4eo53C9FrXENVL9arlM/aNvVhtt9gEGHcU6Htj76z7YcuOXtCXB7GgU2Nmcw==","repository":{"url":"git+https://github.com/interrobangc/typescript-errors.git","type":"git"},"_npmVersion":"10.9.0","description":"Minimal type safe error handling for TypeScript","directories":{},"_nodeVersion":"22.12.0","_hasShrinkwrap":false,"devDependencies":{"jiti":"^2.4.2","eslint":"^9.19.0","vitest":"^3.0.4","prettier":"^3.4.2","@eslint/js":"^9.19.0","typescript":"^5.7.3","@types/node":"^22.12.0","npm-run-all":"^4.1.5","@eslint/compat":"^1.2.6","typescript-eslint":"^8.22.0","@vitest/coverage-v8":"^3.0.4","eslint-plugin-import":"^2.31.0","eslint-plugin-sonarjs":"^3.0.1","eslint-config-prettier":"^10.0.1","@types/eslint-config-prettier":"^6.11.3"},"_npmOperationalInternal":{"tmp":"tmp/typescript-errors_1.0.0_1738433578931_0.11874941460144095","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"typescript-errors","version":"1.1.0","keywords":[],"author":{"name":"bo@interrobang.consulting"},"license":"MIT","_id":"typescript-errors@1.1.0","maintainers":[{"name":"robert-bo-davis","email":"bo@interrobang.consulting"}],"homepage":"https://github.com/interrobangc/typescript-errors","bugs":{"url":"https://github.com/interrobangc/typescript-errors/issues"},"dist":{"shasum":"93528c50597fe15291c0b4fc986d9d8508e06265","tarball":"https://registry.npmjs.org/typescript-errors/-/typescript-errors-1.1.0.tgz","fileCount":12,"integrity":"sha512-bUY4nmAqZ8ZTVJffzhmpHy25yZpbq9Y5nQKdITW1u1U9Vm/AEX1Z72UAZJoXLFSrVfaizXI8NMCSiMiI5ZJjfQ==","signatures":[{"sig":"MEUCIQDKriDQ4zI7T9FSzlCzhaHqgMpjfqVl6pUWIQQlukj9UQIgYZLi5reooA8jZ0IqvrTP1sxzI2RcnVK3uP960u4upU0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23775},"main":"dist/index.js","type":"module","_from":"file:typescript-errors-1.1.0.tgz","types":"dist/index.d.ts","scripts":{"lint":"run-p lint:prettier lint:eslint","test":"run-p lint:fix typecheck test:unit","build":"tsc","lint:fix":"run-p lint:prettier:fix lint:eslint:fix","test:unit":"vitest run --coverage","typecheck":"tsc --noEmit --project tsconfig.test.json","npmPublish":"run-s test build npmPublish:run","lint:eslint":"eslint .","lint:prettier":"prettier . --check","npmPublish:run":"pnpm publish --access public","lint:eslint:fix":"eslint . --fix","test:unit:watch":"vitest","test:integration":"vitest run --test-timeout=120000 --config ./vitest.integration.ts","lint:prettier:fix":"prettier . --write"},"_npmUser":{"name":"robert-bo-davis","email":"bo@interrobang.consulting"},"_resolved":"/private/var/folders/cf/8rnx8bz17xbgc2v70hjzb04w0000gn/T/681ebc90cb5b8b0a891d0608cb61bf8b/typescript-errors-1.1.0.tgz","_integrity":"sha512-bUY4nmAqZ8ZTVJffzhmpHy25yZpbq9Y5nQKdITW1u1U9Vm/AEX1Z72UAZJoXLFSrVfaizXI8NMCSiMiI5ZJjfQ==","repository":{"url":"git+https://github.com/interrobangc/typescript-errors.git","type":"git"},"_npmVersion":"10.9.0","description":"Minimal type safe error handling for TypeScript","directories":{},"_nodeVersion":"22.12.0","_hasShrinkwrap":false,"devDependencies":{"jiti":"^2.4.2","eslint":"^9.19.0","vitest":"^3.0.4","prettier":"^3.4.2","@eslint/js":"^9.19.0","typescript":"^5.7.3","@types/node":"^22.12.0","npm-run-all":"^4.1.5","@eslint/compat":"^1.2.6","typescript-eslint":"^8.22.0","@vitest/coverage-v8":"^3.0.4","eslint-plugin-import":"^2.31.0","eslint-plugin-sonarjs":"^3.0.1","eslint-config-prettier":"^10.0.1","@types/eslint-config-prettier":"^6.11.3"},"_npmOperationalInternal":{"tmp":"tmp/typescript-errors_1.1.0_1740754081875_0.08662046723873962","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"typescript-errors","version":"1.1.1","description":"Minimal type safe error handling for TypeScript","main":"dist/index.js","types":"dist/index.d.ts","type":"module","repository":{"type":"git","url":"git+https://github.com/interrobangc/typescript-errors.git"},"homepage":"https://github.com/interrobangc/typescript-errors","bugs":{"url":"https://github.com/interrobangc/typescript-errors/issues"},"keywords":[],"author":{"name":"bo@interrobang.consulting"},"license":"MIT","devDependencies":{"@eslint/compat":"^1.2.6","@eslint/js":"^9.19.0","@types/eslint-config-prettier":"^6.11.3","@types/node":"^22.12.0","@vitest/coverage-v8":"^3.0.4","eslint":"^9.19.0","eslint-config-prettier":"^10.0.1","eslint-plugin-import":"^2.31.0","eslint-plugin-sonarjs":"^3.0.1","jiti":"^2.4.2","npm-run-all":"^4.1.5","prettier":"^3.4.2","typescript":"^5.7.3","typescript-eslint":"^8.22.0","vitest":"^3.0.4"},"scripts":{"build":"tsc","npmPublish":"run-s test build npmPublish:run","npmPublish:run":"pnpm publish --access public","test":"run-p lint:fix typecheck test:unit","test:integration":"vitest run --test-timeout=120000 --config ./vitest.integration.ts","test:unit":"vitest run --coverage","test:unit:watch":"vitest","lint":"run-p lint:prettier lint:eslint","lint:fix":"run-p lint:prettier:fix lint:eslint:fix","lint:prettier":"prettier . --check","lint:prettier:fix":"prettier . --write","lint:eslint":"eslint .","lint:eslint:fix":"eslint . --fix","typecheck":"tsc --noEmit --project tsconfig.test.json"},"_id":"typescript-errors@1.1.1","_integrity":"sha512-d2siuUXZ1fmYi27UG5kRu/dAoWNUEdq8hOVvPkfYEHGoHvDuJp3ZNto9BH87s+jA3A/3LipJ7T240XUMR6qBMA==","_resolved":"/private/var/folders/cf/8rnx8bz17xbgc2v70hjzb04w0000gn/T/24f87d10aca3bac9295e7ffff123d445/typescript-errors-1.1.1.tgz","_from":"file:typescript-errors-1.1.1.tgz","_nodeVersion":"22.12.0","_npmVersion":"10.9.0","dist":{"integrity":"sha512-d2siuUXZ1fmYi27UG5kRu/dAoWNUEdq8hOVvPkfYEHGoHvDuJp3ZNto9BH87s+jA3A/3LipJ7T240XUMR6qBMA==","shasum":"775e51a51c531ad7928d1fa630775e5483869aff","tarball":"https://registry.npmjs.org/typescript-errors/-/typescript-errors-1.1.1.tgz","fileCount":12,"unpackedSize":24002,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDJ7ylIIGLl9yZ/xgZO5zuCRPvaKcHt918jswPOoOpIewIhAOjTxz8JOJ88TUhMBv6I3DMwkH2Sz8QzIdmMklk7IPB3"}]},"_npmUser":{"name":"robert-bo-davis","email":"bo@interrobang.consulting"},"directories":{},"maintainers":[{"name":"robert-bo-davis","email":"bo@interrobang.consulting"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/typescript-errors_1.1.1_1740754205770_0.27096488078873127"},"_hasShrinkwrap":false}},"time":{"created":"2025-01-31T20:49:48.178Z","modified":"2025-02-28T14:50:06.128Z","0.1.0":"2025-01-31T20:49:48.465Z","0.1.1":"2025-01-31T20:51:48.943Z","0.1.2":"2025-01-31T20:58:10.102Z","0.1.3":"2025-01-31T21:10:54.473Z","0.1.4":"2025-01-31T21:20:10.617Z","0.1.5":"2025-01-31T21:25:00.573Z","0.1.6":"2025-01-31T22:49:47.270Z","0.1.7":"2025-02-01T14:07:38.360Z","0.1.8":"2025-02-01T14:21:22.259Z","0.1.9":"2025-02-01T14:36:51.259Z","0.9.0":"2025-02-01T15:38:09.993Z","0.9.1":"2025-02-01T16:36:05.858Z","0.9.2":"2025-02-01T16:37:13.642Z","1.0.0":"2025-02-01T18:12:59.109Z","1.1.0":"2025-02-28T14:48:02.091Z","1.1.1":"2025-02-28T14:50:05.939Z"},"bugs":{"url":"https://github.com/interrobangc/typescript-errors/issues"},"author":{"name":"bo@interrobang.consulting"},"license":"MIT","homepage":"https://github.com/interrobangc/typescript-errors","keywords":[],"repository":{"type":"git","url":"git+https://github.com/interrobangc/typescript-errors.git"},"description":"Minimal type safe error handling for TypeScript","maintainers":[{"name":"robert-bo-davis","email":"bo@interrobang.consulting"}],"readme":"# typescript-errors\n\nTypeScript library for creating and handling type safe errors without the use of throw statements.\n\n## Why?\n\nThere are quite a few other packages out there that solve the same problem as this one, but they are all a bit complex and hard to understand without a deep grasp of typescript or Functional Programming.\n\nThis package is designed so that the highly opinionated pattern is as simple to understand as possible while still being type safe and easy to use.\n\n### The Problem\n\nThrowing errors in TypeScript makes it impossible for typescript to infer that a function may throw. This package aims to solve that problem while making it easier to split control flow based on the type of error that bubbles up from underlying code.\n\n### The Solution\n\nStop throwing errors. Instead, we use a few simple functions to wrap our code and handle errors in a type safe way. When you call a function that may fail, you can check the result to see if it is an error or not. If you try to access data returned from a function that may fail, you will be forced to handle the error case first. This leads to a much more robust and type safe codebase.\n\nUnder the hood we still use an extended Error class so that the error can be used like a normal error if needed.\n\n## How\n\n### The Functions\n\nThe pattern is based around 2 main function types:\n\n#### May fail functions\n\nThese are helper functions that wrap your code and return an error if something goes wrong. There are 3 convenience functions for these:\n\n- `mayFail` - A function that takes a function and returns an error if the function throws.\n- `promiseMayFail` - A function that takes a promise and returns an error if the promise rejects.\n- `promiseMapMayFail` - A function that takes an array of promises and returns an array of errors if any of the promises reject.\n\n#### Is Error\n\nThe `isError()` function is a type guard that takes a value and returns true if the value is an error. It accepts an optional error code to check against so that you can handle errors differently based on the error code that bubbles up.\n\nThe `throwIfError()` function will throw the error if the value is a typescript error. It accepts an optional error code to throw so that you can handle errors differently based on the error code that bubbles up. There are times when you actually want to throw an error and this is the function to use.\n\n#### Utility functions\n\nThe `newError()` function creates a new typescript error class. This is useful if you need to create an error without calling a mayFail function.\n\n## Basic Usage\n\n### Initialize the package using your error codes and messages\n\n```ts\nimport type { TSErrorDefinition } from 'typescript-errors';\nimport { init } from 'typescript-errors';\n\n// Define your error codes and messages\nconst TS_ERRORS = {\n  'test:error': {\n    message: 'An error occurred',\n    statusCode: 400, // Optional, defaults to 500\n  },\n} as const satisfies TSErrorDefinition;\n\nconst tsErr = init(TS_ERRORS);\n```\n\n### Run something that may fail\n\n```ts\nconst result = tsErr.mayFail(() => {\n  const data = JSON.parse(someJson);\n  return {\n    id: data.id,\n    name: data.name,\n  };\n}, 'test:error');\n\nif (tsErr.isError(result, 'test:error')) {\n  // Handle a specific error differently than other errors\n  console.error(result.message);\n  return result; // bubble up the error\n} else if (tsErr.isError(result)) {\n  // Handle any other error\n  console.error(result.message);\n  return result; // bubble up the error\n}\n\n// Typescript will correctly infer the result type and throw an error if you try\n// to access properties without checking the error type first\nconsole.log(result);\n```\n\n### Run something async that may fail\n\n```ts\nconst result = await tsErr.promiseMayFail(\n  fetch('https://api.example.com'),\n  'test:error',\n);\n\nif (tsErr.isError(result, 'test:error')) {\n  // Handle a specific error differently than other errors\n  console.error(result.message);\n  return result; // bubble up the error\n} else if (tsErr.isError(result)) {\n  // Handle any other error\n  console.error(result.message);\n  return result; // bubble up the error\n}\n\n// Typescript will correctly infer the result type and throw an error if you try\n// to access properties without checking the error type first\nconsole.log(result);\n```\n\n### Run something async that may fail and return a promise\n\n```ts\nconst ids = [1, 2, 3];\nconst result = await tsErr.promiseMapMayFail(\n  ids.map((n) => fetch(`https://api.example.com/${n}`)),\n  'test:error',\n);\n\nif (tsErr.isError(result, 'test:error')) {\n  // Handle a specific error differently than other errors\n  console.error(result.message);\n  return result; // bubble up the error\n} else if (tsErr.isError(result)) {\n  // Handle any other error\n  console.error(result.message);\n  console.dir(result.meta.error, { depth: null }); // Can access error information for items that errored\n  console.dir(result.meta.results, { depth: null }); // Can access results for items that succeeded\n  return result; // bubble up the error\n}\n\n// Typescript will correctly infer the result type and throw an error if you try\n// to access properties without checking the error type first\nconsole.log(result);\n```\n\n### Sometimes you actually WANT to throw (like in a top level remix route)\n\n```ts\nconst result = await tsErr.throwIfError(\n  tsErr.promiseMayFail(Promise.reject(new Error('test')), 'test:error'),\n);\n```\n\n## Error Bubbling\n\nIf you use a mayFail function and the underlying function returns a typescript error, that error will be returned instead of the error you provided. The error you provided will only be returned if the underlying function throws.\n\n```ts\nconst TS_ERRORS = {\n  'test:error': {\n    message: 'Test error',\n    statusCode: 400,\n  },\n  'test:error:somethingElse': {\n    message: 'Something else went wrong',\n    statusCode: 403,\n  },\n} as const satisfies TSErrorDefinition;\n\nconst tsErr = init(TS_ERRORS);\n\nconst result = tsErr.mayFail(() => {\n  return tsErr.newError({ code: 'test:error:somethingElse' });\n}, 'test:error');\n\nconsole.dir(result, { depth: null }); // { code: 'test:error:somethingElse', message: 'Something else went wrong', statusCode: 403 }\n```\n\n## Dynamic error messages\n\nThe message for an error can be a function. This allows you to create errors with dynamic messages.\n\n```ts\nconst TS_ERRORS = {\n  'test:error:functionMessage': {\n    message: (args: TSErrorDefinitionMessageFnArgs) =>\n      `Test error from function ${String(args.code)} ${String(args.meta?.customText)}`,\n    statusCode: 400,\n  },\n} as const satisfies TSErrorDefinition;\n\nconst tsErr = init(TS_ERRORS);\n\nconst result = tsErr.mayFail(() => {\n  throw tsErr.newError({\n    code: 'test:error:functionMessage',\n    meta: { customText: 'custom text' },\n  });\n}, 'test:error:functionMessage');\n\nconsole.error(result.message); // \"Test error from function test:error:functionMessage custom text\"\n```\n\n## The TSError object\n\nThe TSError object is a custom error class that extends the native Error class. It is used to create errors that can be used like a normal error if needed.\n\nIt includes the following properties:\n\n- `cause`: The original error that caused the error to be thrown which includes the stack trace\n- `code`: The error code\n- `message`: The error message\n- `statusCode`: The HTTP status code\n- `meta`: The error meta data\n\nThe TSError object is not intended to be used directly. Instead, you should use the `newError` function to create errors if you need to create an error without calling a mayFail function.\n\n```ts\nconst error = tsErr.newError({\n  code: 'test:error',\n  message: 'Test error',\n  statusCode: 400,\n  meta: { customText: 'custom text' },\n});\n```\n","readmeFilename":"README.md"}