@webpieces/core-util 0.0.0-dev
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 +108 -0
- package/package.json +29 -0
- package/src/index.d.ts +9 -0
- package/src/index.js +14 -0
- package/src/index.js.map +1 -0
- package/src/lib/errorUtils.d.ts +67 -0
- package/src/lib/errorUtils.js +105 -0
- package/src/lib/errorUtils.js.map +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# @webpieces/core-util
|
|
2
|
+
|
|
3
|
+
Utility functions for WebPieces applications. Works in both browser and Node.js environments.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @webpieces/core-util
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
### toError() - Standardized Error Handling
|
|
14
|
+
|
|
15
|
+
The `toError()` function converts any thrown value into a proper Error instance.
|
|
16
|
+
|
|
17
|
+
#### Usage
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { toError } from '@webpieces/core-util';
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
await riskyOperation();
|
|
24
|
+
} catch (err: any) {
|
|
25
|
+
const error = toError(err);
|
|
26
|
+
console.error('Operation failed:', error.message);
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
#### Why use toError()?
|
|
32
|
+
|
|
33
|
+
JavaScript allows throwing any value, not just Errors:
|
|
34
|
+
- `throw "string error"` - loses stack trace
|
|
35
|
+
- `throw { code: 404 }` - not an Error instance
|
|
36
|
+
- `throw null` - extremely unhelpful
|
|
37
|
+
|
|
38
|
+
`toError()` ensures you always have a proper Error object with:
|
|
39
|
+
- Type safety (always returns Error)
|
|
40
|
+
- Stack traces preserved when available
|
|
41
|
+
- Consistent error structure
|
|
42
|
+
- Integration with logging/monitoring
|
|
43
|
+
|
|
44
|
+
#### Enforced Pattern
|
|
45
|
+
|
|
46
|
+
WebPieces projects enforce this pattern via ESLint rule `@webpieces/catch-error-pattern`:
|
|
47
|
+
|
|
48
|
+
**Required:**
|
|
49
|
+
```typescript
|
|
50
|
+
try {
|
|
51
|
+
operation();
|
|
52
|
+
} catch (err: any) {
|
|
53
|
+
const error = toError(err);
|
|
54
|
+
// Handle error...
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Alternative (explicitly ignored errors):**
|
|
59
|
+
```typescript
|
|
60
|
+
try {
|
|
61
|
+
operation();
|
|
62
|
+
} catch (err: any) {
|
|
63
|
+
//const error = toError(err);
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
#### Nested Catch Blocks
|
|
68
|
+
|
|
69
|
+
For nested catches, use numbered suffixes:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
try {
|
|
73
|
+
operation1();
|
|
74
|
+
} catch (err: any) {
|
|
75
|
+
const error = toError(err);
|
|
76
|
+
try {
|
|
77
|
+
rollback();
|
|
78
|
+
} catch (err2: any) {
|
|
79
|
+
const error2 = toError(err2);
|
|
80
|
+
console.error('Rollback failed:', error2);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### Behavior
|
|
86
|
+
|
|
87
|
+
| Input Type | Behavior | Example |
|
|
88
|
+
|------------|----------|---------|
|
|
89
|
+
| Error instance | Returned unchanged | `toError(new Error('msg'))` → same Error |
|
|
90
|
+
| Error-like object | Converts to Error, preserves message/name/stack | `toError({message: 'msg', stack: '...'})` |
|
|
91
|
+
| Object without message | Stringifies object | `toError({code: 404})` → `Error("Non-Error object thrown: {...}")` |
|
|
92
|
+
| String | Wraps in Error | `toError("error")` → `Error("error")` |
|
|
93
|
+
| Number | Converts to string | `toError(404)` → `Error("404")` |
|
|
94
|
+
| null/undefined | Generic message | `toError(null)` → `Error("Null or undefined thrown")` |
|
|
95
|
+
|
|
96
|
+
## Browser Compatibility
|
|
97
|
+
|
|
98
|
+
This package has zero dependencies and works in all modern browsers and Node.js environments.
|
|
99
|
+
|
|
100
|
+
## Related Packages
|
|
101
|
+
|
|
102
|
+
- [@webpieces/dev-config](https://www.npmjs.com/package/@webpieces/dev-config) - Includes ESLint rule that enforces this pattern
|
|
103
|
+
- [@webpieces/core-context](https://www.npmjs.com/package/@webpieces/core-context) - Request context management
|
|
104
|
+
- [@webpieces/http-server](https://www.npmjs.com/package/@webpieces/http-server) - HTTP server
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
Apache-2.0
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@webpieces/core-util",
|
|
3
|
+
"version": "0.0.0-dev",
|
|
4
|
+
"description": "Utility functions for WebPieces - works in browser and Node.js",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "./src/index.js",
|
|
7
|
+
"types": "./src/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./src/index.d.ts",
|
|
11
|
+
"default": "./src/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"webpieces",
|
|
16
|
+
"utilities",
|
|
17
|
+
"error-handling"
|
|
18
|
+
],
|
|
19
|
+
"author": "Dean Hiller",
|
|
20
|
+
"license": "Apache-2.0",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/deanhiller/webpieces-ts.git",
|
|
24
|
+
"directory": "packages/core/core-util"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
}
|
|
29
|
+
}
|
package/src/index.d.ts
ADDED
package/src/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @webpieces/core-util
|
|
4
|
+
*
|
|
5
|
+
* Utility functions for WebPieces applications.
|
|
6
|
+
* This package works in both browser and Node.js environments.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.toError = void 0;
|
|
12
|
+
var errorUtils_1 = require("./lib/errorUtils");
|
|
13
|
+
Object.defineProperty(exports, "toError", { enumerable: true, get: function () { return errorUtils_1.toError; } });
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/core/core-util/src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,+CAA2C;AAAlC,qGAAA,OAAO,OAAA","sourcesContent":["/**\n * @webpieces/core-util\n *\n * Utility functions for WebPieces applications.\n * This package works in both browser and Node.js environments.\n *\n * @packageDocumentation\n */\n\nexport { toError } from './lib/errorUtils';\n"]}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error handling utilities for standardized error processing
|
|
3
|
+
* All catch blocks should use toError() to ensure consistent error handling
|
|
4
|
+
*
|
|
5
|
+
* This pattern is enforced by the @webpieces/eslint-plugin-webpieces rule:
|
|
6
|
+
* `catch-error-pattern`
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Converts unknown error types to Error instances
|
|
10
|
+
*
|
|
11
|
+
* This function standardizes all caught errors into Error objects, ensuring:
|
|
12
|
+
* - Type safety (always returns Error)
|
|
13
|
+
* - Consistent error structure
|
|
14
|
+
* - Proper stack traces
|
|
15
|
+
* - Integration with monitoring/logging systems
|
|
16
|
+
*
|
|
17
|
+
* **WebPieces Pattern**: All catch blocks must follow this pattern:
|
|
18
|
+
* ```typescript
|
|
19
|
+
* try {
|
|
20
|
+
* riskyOperation();
|
|
21
|
+
* } catch (err: any) {
|
|
22
|
+
* const error = toError(err);
|
|
23
|
+
* // Handle error...
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* Alternative (explicitly ignored errors):
|
|
28
|
+
* ```typescript
|
|
29
|
+
* try {
|
|
30
|
+
* riskyOperation();
|
|
31
|
+
* } catch (err: any) {
|
|
32
|
+
* //const error = toError(err);
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @param err - Unknown error from catch block (typed as any)
|
|
37
|
+
* @returns Standardized Error instance
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* // Standard usage
|
|
42
|
+
* try {
|
|
43
|
+
* await riskyOperation();
|
|
44
|
+
* } catch (err: any) {
|
|
45
|
+
* const error = toError(err);
|
|
46
|
+
* console.error('Operation failed:', error.message);
|
|
47
|
+
* throw error;
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* // Nested catch blocks
|
|
54
|
+
* try {
|
|
55
|
+
* await operation1();
|
|
56
|
+
* } catch (err: any) {
|
|
57
|
+
* const error = toError(err);
|
|
58
|
+
* try {
|
|
59
|
+
* await rollback();
|
|
60
|
+
* } catch (err2: any) {
|
|
61
|
+
* const error2 = toError(err2);
|
|
62
|
+
* console.error('Rollback failed:', error2);
|
|
63
|
+
* }
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare function toError(err: any): Error;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Error handling utilities for standardized error processing
|
|
4
|
+
* All catch blocks should use toError() to ensure consistent error handling
|
|
5
|
+
*
|
|
6
|
+
* This pattern is enforced by the @webpieces/eslint-plugin-webpieces rule:
|
|
7
|
+
* `catch-error-pattern`
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.toError = toError;
|
|
11
|
+
/**
|
|
12
|
+
* Converts unknown error types to Error instances
|
|
13
|
+
*
|
|
14
|
+
* This function standardizes all caught errors into Error objects, ensuring:
|
|
15
|
+
* - Type safety (always returns Error)
|
|
16
|
+
* - Consistent error structure
|
|
17
|
+
* - Proper stack traces
|
|
18
|
+
* - Integration with monitoring/logging systems
|
|
19
|
+
*
|
|
20
|
+
* **WebPieces Pattern**: All catch blocks must follow this pattern:
|
|
21
|
+
* ```typescript
|
|
22
|
+
* try {
|
|
23
|
+
* riskyOperation();
|
|
24
|
+
* } catch (err: any) {
|
|
25
|
+
* const error = toError(err);
|
|
26
|
+
* // Handle error...
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* Alternative (explicitly ignored errors):
|
|
31
|
+
* ```typescript
|
|
32
|
+
* try {
|
|
33
|
+
* riskyOperation();
|
|
34
|
+
* } catch (err: any) {
|
|
35
|
+
* //const error = toError(err);
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @param err - Unknown error from catch block (typed as any)
|
|
40
|
+
* @returns Standardized Error instance
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* // Standard usage
|
|
45
|
+
* try {
|
|
46
|
+
* await riskyOperation();
|
|
47
|
+
* } catch (err: any) {
|
|
48
|
+
* const error = toError(err);
|
|
49
|
+
* console.error('Operation failed:', error.message);
|
|
50
|
+
* throw error;
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* // Nested catch blocks
|
|
57
|
+
* try {
|
|
58
|
+
* await operation1();
|
|
59
|
+
* } catch (err: any) {
|
|
60
|
+
* const error = toError(err);
|
|
61
|
+
* try {
|
|
62
|
+
* await rollback();
|
|
63
|
+
* } catch (err2: any) {
|
|
64
|
+
* const error2 = toError(err2);
|
|
65
|
+
* console.error('Rollback failed:', error2);
|
|
66
|
+
* }
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
function toError(err) {
|
|
71
|
+
// If already an Error instance, return it directly
|
|
72
|
+
if (err instanceof Error) {
|
|
73
|
+
return err;
|
|
74
|
+
}
|
|
75
|
+
// If it's an object with a message property, create Error from it
|
|
76
|
+
if (err && typeof err === 'object') {
|
|
77
|
+
if ('message' in err) {
|
|
78
|
+
const error = new Error(String(err.message));
|
|
79
|
+
// Preserve stack trace if available
|
|
80
|
+
if ('stack' in err && typeof err.stack === 'string') {
|
|
81
|
+
error.stack = err.stack;
|
|
82
|
+
}
|
|
83
|
+
// Preserve error name if available
|
|
84
|
+
if ('name' in err && typeof err.name === 'string') {
|
|
85
|
+
error.name = err.name;
|
|
86
|
+
}
|
|
87
|
+
return error;
|
|
88
|
+
}
|
|
89
|
+
// For objects without message, try to stringify
|
|
90
|
+
try {
|
|
91
|
+
const message = JSON.stringify(err);
|
|
92
|
+
return new Error(`Non-Error object thrown: ${message}`);
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
// eslint-disable-next-line @webpieces/catch-error-pattern
|
|
96
|
+
// NOTE: Intentionally not calling toError() here to prevent infinite recursion
|
|
97
|
+
// in error recovery path. This is the ONLY acceptable exception to the pattern.
|
|
98
|
+
return new Error('Non-Error object thrown (unable to stringify)');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// For primitives (string, number, boolean, null, undefined)
|
|
102
|
+
const message = err == null ? 'Null or undefined thrown' : String(err);
|
|
103
|
+
return new Error(message);
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=errorUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorUtils.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/lib/errorUtils.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AA6DH,0BAuCC;AAlGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,SAAgB,OAAO,CAAC,GAAQ;IAC9B,mDAAmD;IACnD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,GAAG,CAAC;IACb,CAAC;IAED,kEAAkE;IAClE,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACnC,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YAE7C,oCAAoC;YACpC,IAAI,OAAO,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACpD,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YAC1B,CAAC;YAED,mCAAmC;YACnC,IAAI,MAAM,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAClD,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YACxB,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;QAED,gDAAgD;QAChD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACpC,OAAO,IAAI,KAAK,CAAC,4BAA4B,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,0DAA0D;YAC1D,+EAA+E;YAC/E,gFAAgF;YAChF,OAAO,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,4DAA4D;IAC5D,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACvE,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC5B,CAAC","sourcesContent":["/**\n * Error handling utilities for standardized error processing\n * All catch blocks should use toError() to ensure consistent error handling\n *\n * This pattern is enforced by the @webpieces/eslint-plugin-webpieces rule:\n * `catch-error-pattern`\n */\n\n/**\n * Converts unknown error types to Error instances\n *\n * This function standardizes all caught errors into Error objects, ensuring:\n * - Type safety (always returns Error)\n * - Consistent error structure\n * - Proper stack traces\n * - Integration with monitoring/logging systems\n *\n * **WebPieces Pattern**: All catch blocks must follow this pattern:\n * ```typescript\n * try {\n * riskyOperation();\n * } catch (err: any) {\n * const error = toError(err);\n * // Handle error...\n * }\n * ```\n *\n * Alternative (explicitly ignored errors):\n * ```typescript\n * try {\n * riskyOperation();\n * } catch (err: any) {\n * //const error = toError(err);\n * }\n * ```\n *\n * @param err - Unknown error from catch block (typed as any)\n * @returns Standardized Error instance\n *\n * @example\n * ```typescript\n * // Standard usage\n * try {\n * await riskyOperation();\n * } catch (err: any) {\n * const error = toError(err);\n * console.error('Operation failed:', error.message);\n * throw error;\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Nested catch blocks\n * try {\n * await operation1();\n * } catch (err: any) {\n * const error = toError(err);\n * try {\n * await rollback();\n * } catch (err2: any) {\n * const error2 = toError(err2);\n * console.error('Rollback failed:', error2);\n * }\n * }\n * ```\n */\nexport function toError(err: any): Error {\n // If already an Error instance, return it directly\n if (err instanceof Error) {\n return err;\n }\n\n // If it's an object with a message property, create Error from it\n if (err && typeof err === 'object') {\n if ('message' in err) {\n const error = new Error(String(err.message));\n\n // Preserve stack trace if available\n if ('stack' in err && typeof err.stack === 'string') {\n error.stack = err.stack;\n }\n\n // Preserve error name if available\n if ('name' in err && typeof err.name === 'string') {\n error.name = err.name;\n }\n\n return error;\n }\n\n // For objects without message, try to stringify\n try {\n const message = JSON.stringify(err);\n return new Error(`Non-Error object thrown: ${message}`);\n } catch (err: any) {\n // eslint-disable-next-line @webpieces/catch-error-pattern\n // NOTE: Intentionally not calling toError() here to prevent infinite recursion\n // in error recovery path. This is the ONLY acceptable exception to the pattern.\n return new Error('Non-Error object thrown (unable to stringify)');\n }\n }\n\n // For primitives (string, number, boolean, null, undefined)\n const message = err == null ? 'Null or undefined thrown' : String(err);\n return new Error(message);\n}\n"]}
|