@lssm/lib.error 0.0.0-canary-20251120170226
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -0
- package/dist/appError.d.ts +17 -0
- package/dist/appError.d.ts.map +1 -0
- package/dist/appError.js +2 -0
- package/dist/appError.js.map +1 -0
- package/dist/codes.d.ts +19 -0
- package/dist/codes.d.ts.map +1 -0
- package/dist/codes.js +2 -0
- package/dist/codes.js.map +1 -0
- package/dist/http.d.ts +11 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +2 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# @lssm/lib.error
|
|
2
|
+
|
|
3
|
+
Standardized error handling primitives for LSSM applications.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
To provide a consistent error model across the monorepo, enabling predictable error handling, serialization, and mapping to HTTP status codes and GraphQL errors.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @lssm/lib.error
|
|
13
|
+
# or
|
|
14
|
+
bun add @lssm/lib.error
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Key Concepts
|
|
18
|
+
|
|
19
|
+
- **AppError**: Base class for all application errors, carrying a `code` and optional `meta` data.
|
|
20
|
+
- **Error Codes**: Centralized enum/registry of error codes (e.g., `NOT_FOUND`, `UNAUTHORIZED`).
|
|
21
|
+
- **HTTP Mapping**: Utilities to map error codes to HTTP status codes (e.g., `NOT_FOUND` -> 404).
|
|
22
|
+
|
|
23
|
+
## Exports
|
|
24
|
+
|
|
25
|
+
- `AppError`: The base error class.
|
|
26
|
+
- `codes`: Error code definitions.
|
|
27
|
+
- `http`: HTTP status code helpers.
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { AppError, ErrorCode } from '@lssm/lib.error';
|
|
33
|
+
|
|
34
|
+
// Throwing a known error
|
|
35
|
+
throw new AppError(ErrorCode.NOT_FOUND, 'User not found', { userId: 123 });
|
|
36
|
+
|
|
37
|
+
// Catching and handling
|
|
38
|
+
try {
|
|
39
|
+
// ...
|
|
40
|
+
} catch (err) {
|
|
41
|
+
if (err instanceof AppError) {
|
|
42
|
+
console.log(err.code); // 'NOT_FOUND'
|
|
43
|
+
console.log(err.meta); // { userId: 123 }
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ErrorCode } from "./codes.js";
|
|
2
|
+
|
|
3
|
+
//#region src/appError.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generic application error with code and optional details.
|
|
7
|
+
*/
|
|
8
|
+
declare class AppError extends Error {
|
|
9
|
+
code: ErrorCode;
|
|
10
|
+
details?: Record<string, unknown> | undefined;
|
|
11
|
+
constructor(code: ErrorCode, message: string, details?: Record<string, unknown> | undefined);
|
|
12
|
+
}
|
|
13
|
+
/** Type guard to detect AppError */
|
|
14
|
+
declare function isAppError(err: unknown): err is AppError;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { AppError, isAppError };
|
|
17
|
+
//# sourceMappingURL=appError.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appError.d.ts","names":[],"sources":["../src/appError.ts"],"sourcesContent":[],"mappings":";;;;;;AAKA;AAEiB,cAFJ,QAAA,SAAiB,KAAA,CAEb;EAEI,IAAA,EAFJ,SAEI;EAFJ,OAAA,CAAA,EAEI,MAFJ,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,SAAA;EAEI,WAAA,CAAA,IAAA,EAFJ,SAEI,EAAA,OAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,SAAA;;;AASL,iBAAA,UAAA,CAAiC,GAAQ,EAAA,OAAA,CAAA,EAAA,GAAA,IAAR,QAAQ"}
|
package/dist/appError.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appError.js","names":["code: ErrorCode","details?: Record<string, unknown>"],"sources":["../src/appError.ts"],"sourcesContent":["import { ErrorCode } from './codes';\n\n/**\n * Generic application error with code and optional details.\n */\nexport class AppError extends Error {\n constructor(\n public code: ErrorCode,\n message: string,\n public details?: Record<string, unknown>\n ) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = 'AppError';\n }\n}\n\n/** Type guard to detect AppError */\nexport function isAppError(err: unknown): err is AppError {\n return err instanceof AppError;\n}\n"],"mappings":"AAKA,IAAa,EAAb,cAA8B,KAAM,CAClC,YACE,EACA,EACA,EACA,CACA,MAAM,EAAQ,CAJP,KAAA,KAAA,EAEA,KAAA,QAAA,EAGP,OAAO,eAAe,KAAM,IAAI,OAAO,UAAU,CACjD,KAAK,KAAO,aAKhB,SAAgB,EAAW,EAA+B,CACxD,OAAO,aAAe"}
|
package/dist/codes.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/codes.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Centralised error codes used across services.
|
|
4
|
+
* Extend this enum to add more domain-specific codes.
|
|
5
|
+
*/
|
|
6
|
+
declare enum ErrorCode {
|
|
7
|
+
UNAUTHENTICATED = "UNAUTHENTICATED",
|
|
8
|
+
FORBIDDEN = "FORBIDDEN",
|
|
9
|
+
NOT_FOUND = "NOT_FOUND",
|
|
10
|
+
INVALID_INPUT = "INVALID_INPUT",
|
|
11
|
+
CONFLICT = "CONFLICT",
|
|
12
|
+
RATE_LIMITED = "RATE_LIMITED",
|
|
13
|
+
SERVER_ERROR = "SERVER_ERROR",
|
|
14
|
+
POLICY_DENIED = "POLICY_DENIED",
|
|
15
|
+
}
|
|
16
|
+
declare function isKnownErrorCode(code: string): code is ErrorCode;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { ErrorCode, isKnownErrorCode };
|
|
19
|
+
//# sourceMappingURL=codes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codes.d.ts","names":[],"sources":["../src/codes.ts"],"sourcesContent":[],"mappings":";;AAIA;AAYA;;aAZY,SAAA;;;;;;;;;;iBAYI,gBAAA,wBAAwC"}
|
package/dist/codes.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
let e=function(e){return e.UNAUTHENTICATED=`UNAUTHENTICATED`,e.FORBIDDEN=`FORBIDDEN`,e.NOT_FOUND=`NOT_FOUND`,e.INVALID_INPUT=`INVALID_INPUT`,e.CONFLICT=`CONFLICT`,e.RATE_LIMITED=`RATE_LIMITED`,e.SERVER_ERROR=`SERVER_ERROR`,e.POLICY_DENIED=`POLICY_DENIED`,e}({});function t(t){return Object.values(e).includes(t)}export{e as ErrorCode,t as isKnownErrorCode};
|
|
2
|
+
//# sourceMappingURL=codes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codes.js","names":[],"sources":["../src/codes.ts"],"sourcesContent":["/**\n * Centralised error codes used across services.\n * Extend this enum to add more domain-specific codes.\n */\nexport enum ErrorCode {\n UNAUTHENTICATED = 'UNAUTHENTICATED',\n FORBIDDEN = 'FORBIDDEN',\n NOT_FOUND = 'NOT_FOUND',\n INVALID_INPUT = 'INVALID_INPUT',\n CONFLICT = 'CONFLICT',\n RATE_LIMITED = 'RATE_LIMITED',\n SERVER_ERROR = 'SERVER_ERROR',\n POLICY_DENIED = 'POLICY_DENIED',\n // add more codes here\n}\n\nexport function isKnownErrorCode(code: string): code is ErrorCode {\n return Object.values(ErrorCode).includes(code as ErrorCode);\n}\n"],"mappings":"AAIA,IAAY,EAAA,SAAA,EAAL,OACL,GAAA,gBAAA,kBACA,EAAA,UAAA,YACA,EAAA,UAAA,YACA,EAAA,cAAA,gBACA,EAAA,SAAA,WACA,EAAA,aAAA,eACA,EAAA,aAAA,eACA,EAAA,cAAA,uBAIF,SAAgB,EAAiB,EAAiC,CAChE,OAAO,OAAO,OAAO,EAAU,CAAC,SAAS,EAAkB"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ErrorCode } from "./codes.js";
|
|
2
|
+
|
|
3
|
+
//#region src/http.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Map known error codes to HTTP status codes.
|
|
7
|
+
*/
|
|
8
|
+
declare function httpStatus(code: ErrorCode): number;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { httpStatus };
|
|
11
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","names":[],"sources":["../src/http.ts"],"sourcesContent":[],"mappings":";;;;;;AAMA;iBAAgB,UAAA,OAAiB"}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{ErrorCode as e}from"./codes.js";function t(t){switch(t){case e.UNAUTHENTICATED:return 401;case e.FORBIDDEN:case e.POLICY_DENIED:return 403;case e.NOT_FOUND:return 404;case e.INVALID_INPUT:return 400;case e.CONFLICT:return 409;case e.RATE_LIMITED:return 429;default:return 500}}export{t as httpStatus};
|
|
2
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","names":[],"sources":["../src/http.ts"],"sourcesContent":["import { isAppError } from './appError';\nimport { ErrorCode } from './codes';\n\n/**\n * Map known error codes to HTTP status codes.\n */\nexport function httpStatus(code: ErrorCode): number {\n switch (code) {\n case ErrorCode.UNAUTHENTICATED:\n return 401;\n case ErrorCode.FORBIDDEN:\n case ErrorCode.POLICY_DENIED:\n return 403;\n case ErrorCode.NOT_FOUND:\n return 404;\n case ErrorCode.INVALID_INPUT:\n return 400;\n case ErrorCode.CONFLICT:\n return 409;\n case ErrorCode.RATE_LIMITED:\n return 429;\n default:\n return 500;\n }\n}\n\n/**\n * Convert AppError or unknown error into a Problem JSON response body and status code.\n */\n// export function toHttpResponse(err: unknown): { status: number; body: any } {\n// if (isAppError(err)) {\n// const status = httpStatus(err.code);\n// return {\n// status,\n// body: {\n// type: `https://api.chaman.dev/errors/${err.code.toLowerCase()}`,\n// title: err.message,\n// detail: err.details ?? null,\n// status,\n// },\n// };\n// }\n// // Unknown error: hide internal details\n// return {\n// status: 500,\n// body: {\n// type: 'https://api.chaman.dev/errors/server_error',\n// title: 'Unexpected Error',\n// detail: null,\n// status: 500,\n// },\n// };\n// }\n"],"mappings":"uCAMA,SAAgB,EAAW,EAAyB,CAClD,OAAQ,EAAR,CACE,KAAK,EAAU,gBACb,MAAO,KACT,KAAK,EAAU,UACf,KAAK,EAAU,cACb,MAAO,KACT,KAAK,EAAU,UACb,MAAO,KACT,KAAK,EAAU,cACb,MAAO,KACT,KAAK,EAAU,SACb,MAAO,KACT,KAAK,EAAU,aACb,MAAO,KACT,QACE,MAAO"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ErrorCode as e,isKnownErrorCode as t}from"./codes.js";import{AppError as n,isAppError as r}from"./appError.js";import{httpStatus as i}from"./http.js";export{n as AppError,e as ErrorCode,i as httpStatus,r as isAppError,t as isKnownErrorCode};
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lssm/lib.error",
|
|
3
|
+
"version": "0.0.0-canary-20251120170226",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"build": "bun build:bundle && bun build:types",
|
|
6
|
+
"build:bundle": "tsdown",
|
|
7
|
+
"build:types": "tsc --noEmit",
|
|
8
|
+
"dev": "bun build:bundle --watch",
|
|
9
|
+
"clean": "rimraf dist .turbo",
|
|
10
|
+
"lint": "bun lint:fix",
|
|
11
|
+
"lint:fix": "eslint src --fix",
|
|
12
|
+
"lint:check": "eslint src"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@lssm/tool.typescript": "0.0.0-canary-20251120170226",
|
|
16
|
+
"tsdown": "^0.15.9",
|
|
17
|
+
"typescript": "^5.9.3"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"elysia": "^1.4.11",
|
|
22
|
+
"express": "^5.1.0",
|
|
23
|
+
"next": "15.5.6"
|
|
24
|
+
},
|
|
25
|
+
"type": "module",
|
|
26
|
+
"main": "./dist/index.js",
|
|
27
|
+
"module": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"README.md"
|
|
32
|
+
],
|
|
33
|
+
"exports": {
|
|
34
|
+
".": "./dist/index.js",
|
|
35
|
+
"./appError": "./dist/appError.js",
|
|
36
|
+
"./codes": "./dist/codes.js",
|
|
37
|
+
"./http": "./dist/http.js",
|
|
38
|
+
"./*": "./*"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"exports": {
|
|
42
|
+
".": "./dist/index.js",
|
|
43
|
+
"./appError": "./dist/appError.js",
|
|
44
|
+
"./codes": "./dist/codes.js",
|
|
45
|
+
"./http": "./dist/http.js",
|
|
46
|
+
"./*": "./*"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|