@taicode/common-base 1.7.5 → 3.0.1

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.
@@ -80,6 +80,9 @@ export declare class UserError<T extends string = string> extends Error {
80
80
  cause?: unknown;
81
81
  };
82
82
  isError(error: unknown): error is Error;
83
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
84
+ prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
85
+ stackTraceLimit: number;
83
86
  };
84
87
  }
85
88
  /**
@@ -117,6 +120,9 @@ export declare class SystemError<T extends string = string> extends Error {
117
120
  cause?: unknown;
118
121
  };
119
122
  isError(error: unknown): error is Error;
123
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
124
+ prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
125
+ stackTraceLimit: number;
120
126
  };
121
127
  }
122
128
  //# sourceMappingURL=error.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../source/error/error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,eAAe;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,eAAe;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED;;;GAGG;AACH,qBAAa,SAAS,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,KAAK;IAEpD,IAAI,EAAE,CAAC;IACP,OAAO,CAAC,EAAE,YAAY;IACtB,OAAO,EAAE,MAAM;gBAFf,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,YAAY,YAAA,EACtB,OAAO,GAAE,MAAW;IAM7B,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC;IAI3E;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,UAAU,EAAE,KAAK;2DAY3D,KAAK,8BAAW,YACjB,MAAM;;+BARS,KAAK,8BAAW;;;;;;QAE1C,kBAAkB;wBACiC,8BAAW;kBAa7C,OAAO,GAAG,KAAK;;+BAhBN,KAAK,8BAAW;;;;;SAgBQ;;;CAKvD;AAED;;;GAGG;AACH,qBAAa,WAAW,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,KAAK;IAEtD,IAAI,EAAE,CAAC;IACP,OAAO,CAAC,EAAE,YAAY;IACtB,OAAO,EAAE,MAAM;gBAFf,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,YAAY,YAAA,EACtB,OAAO,GAAE,MAAW;IAM7B,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAAC,CAAC,CAAC;IAI7E;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,UAAU,EAAE,KAAK;2DAY3D,KAAK,8BAAW,YACjB,MAAM;;+BARS,KAAK,8BAAW;;;;;;QAE1C,kBAAkB;wBACiC,8BAAW;kBAa7C,OAAO,GAAG,KAAK;;+BAhBN,KAAK,8BAAW;;;;;SAgBU;;;CAKzD"}
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../source/error/error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,eAAe;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,eAAe;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAmBD;;;GAGG;AACH,qBAAa,SAAS,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,KAAK;IAEpD,IAAI,EAAE,CAAC;IACP,OAAO,CAAC,EAAE,YAAY;IACtB,OAAO,EAAE,MAAM;gBAFf,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,YAAY,YAAA,EACtB,OAAO,GAAE,MAAW;IAO7B,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC;IAI3E;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,UAAU,EAAE,KAAK;2DAa3D,KAAK,8BAAW,YACjB,MAAM;;+BARS,KAAK,8BAAW;;;;;;QAE1C,kBAAkB;wBACiC,8BAAW;kBAe7C,OAAO,GAAG,KAAK;;+BAlBN,KAAK,8BAAW;;;;;SAkBQ;;;;;;CAKvD;AAED;;;GAGG;AACH,qBAAa,WAAW,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,KAAK;IAEtD,IAAI,EAAE,CAAC;IACP,OAAO,CAAC,EAAE,YAAY;IACtB,OAAO,EAAE,MAAM;gBAFf,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,YAAY,YAAA,EACtB,OAAO,GAAE,MAAW;IAO7B,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAAC,CAAC,CAAC;IAI7E;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,UAAU,EAAE,KAAK;2DAa3D,KAAK,8BAAW,YACjB,MAAM;;+BARS,KAAK,8BAAW;;;;;;QAE1C,kBAAkB;wBACiC,8BAAW;kBAe7C,OAAO,GAAG,KAAK;;+BAlBN,KAAK,8BAAW;;;;;SAkBU;;;;;;CAKzD"}
@@ -35,6 +35,20 @@
35
35
  * }
36
36
  * ```
37
37
  */
38
+ /**
39
+ * 用于标识 UserError 实例的品牌标记
40
+ * 使用 Symbol.for 确保跨模块/编译后仍可正确识别
41
+ */
42
+ const USER_ERROR_BRAND = Symbol.for('@taicode/common/UserError');
43
+ /**
44
+ * 用于标识 SystemError 实例的品牌标记
45
+ * 使用 Symbol.for 确保跨模块/编译后仍可正确识别
46
+ */
47
+ const SYSTEM_ERROR_BRAND = Symbol.for('@taicode/common/SystemError');
48
+ /** 品牌标记检查辅助函数 */
49
+ function hasBrand(value, brand) {
50
+ return typeof value === 'object' && value !== null && value[brand] === true;
51
+ }
38
52
  /**
39
53
  * 用户可见的错误
40
54
  * 用于表示用户操作导致的错误,如验证失败、权限不足等
@@ -49,9 +63,10 @@ export class UserError extends Error {
49
63
  this.context = context;
50
64
  this.message = message;
51
65
  this.name = 'UserError';
66
+ Object.defineProperty(this, USER_ERROR_BRAND, { value: true });
52
67
  }
53
68
  static is(error) {
54
- return error instanceof UserError;
69
+ return hasBrand(error, USER_ERROR_BRAND);
55
70
  }
56
71
  /**
57
72
  * 定义一个绑定了特定错误类型的 UserError 类
@@ -59,6 +74,7 @@ export class UserError extends Error {
59
74
  * @returns 返回绑定了特定类型的 UserError 类
60
75
  */
61
76
  static define(errorTypes) {
77
+ const BOUND_BRAND = Symbol();
62
78
  return class BoundUserError extends Error {
63
79
  type;
64
80
  context;
@@ -69,9 +85,11 @@ export class UserError extends Error {
69
85
  this.name = 'UserError';
70
86
  this.type = type;
71
87
  this.context = context;
88
+ Object.defineProperty(this, USER_ERROR_BRAND, { value: true });
89
+ Object.defineProperty(this, BOUND_BRAND, { value: true });
72
90
  }
73
91
  static is(error) {
74
- return error instanceof BoundUserError;
92
+ return hasBrand(error, BOUND_BRAND);
75
93
  }
76
94
  };
77
95
  }
@@ -90,9 +108,10 @@ export class SystemError extends Error {
90
108
  this.context = context;
91
109
  this.message = message;
92
110
  this.name = 'SystemError';
111
+ Object.defineProperty(this, SYSTEM_ERROR_BRAND, { value: true });
93
112
  }
94
113
  static is(error) {
95
- return error instanceof SystemError;
114
+ return hasBrand(error, SYSTEM_ERROR_BRAND);
96
115
  }
97
116
  /**
98
117
  * 定义一个绑定了特定错误类型的 SystemError 类
@@ -100,6 +119,7 @@ export class SystemError extends Error {
100
119
  * @returns 返回绑定了特定类型的 SystemError 类
101
120
  */
102
121
  static define(errorTypes) {
122
+ const BOUND_BRAND = Symbol();
103
123
  return class BoundSystemError extends Error {
104
124
  type;
105
125
  context;
@@ -110,9 +130,11 @@ export class SystemError extends Error {
110
130
  this.name = 'SystemError';
111
131
  this.type = type;
112
132
  this.context = context;
133
+ Object.defineProperty(this, SYSTEM_ERROR_BRAND, { value: true });
134
+ Object.defineProperty(this, BOUND_BRAND, { value: true });
113
135
  }
114
136
  static is(error) {
115
- return error instanceof BoundSystemError;
137
+ return hasBrand(error, BOUND_BRAND);
116
138
  }
117
139
  };
118
140
  }
@@ -84,6 +84,17 @@ describe('UserError', () => {
84
84
  expect(error.name).toBe('UserError');
85
85
  }
86
86
  });
87
+ it('在原型链丢失的情况下仍能通过品牌标记正确识别', () => {
88
+ const error = new UserError('TEST_ERROR', undefined, '测试错误');
89
+ // 模拟编译/序列化后原型链丢失的情况
90
+ const plainObj = Object.create(null);
91
+ Object.assign(plainObj, error);
92
+ // 手动复制品牌标记(Symbol.for 在不同模块实例中指向同一个 Symbol)
93
+ const brand = Symbol.for('@taicode/common/UserError');
94
+ Object.defineProperty(plainObj, brand, { value: true });
95
+ expect(plainObj instanceof UserError).toBe(false); // instanceof 失效
96
+ expect(UserError.is(plainObj)).toBe(true); // 品牌标记仍然有效
97
+ });
87
98
  });
88
99
  describe('继承行为', () => {
89
100
  it('应该正确继承Error的所有属性和方法', () => {
@@ -188,6 +199,16 @@ describe('SystemError', () => {
188
199
  expect(error.name).toBe('SystemError');
189
200
  }
190
201
  });
202
+ it('在原型链丢失的情况下仍能通过品牌标记正确识别', () => {
203
+ const error = new SystemError('TEST_ERROR', undefined, '测试错误');
204
+ // 模拟编译/序列化后原型链丢失的情况
205
+ const plainObj = Object.create(null);
206
+ Object.assign(plainObj, error);
207
+ const brand = Symbol.for('@taicode/common/SystemError');
208
+ Object.defineProperty(plainObj, brand, { value: true });
209
+ expect(plainObj instanceof SystemError).toBe(false); // instanceof 失效
210
+ expect(SystemError.is(plainObj)).toBe(true); // 品牌标记仍然有效
211
+ });
191
212
  });
192
213
  describe('继承行为', () => {
193
214
  it('应该正确继承Error的所有属性和方法', () => {
@@ -224,6 +245,22 @@ describe('错误类型区分', () => {
224
245
  expect(userError instanceof Error).toBe(true);
225
246
  expect(systemError instanceof Error).toBe(true);
226
247
  });
248
+ it('define 创建的 BoundError 也能被基类 is 方法识别', () => {
249
+ const MyUserError = UserError.define({
250
+ 'test': {}
251
+ });
252
+ const MySystemError = SystemError.define({
253
+ 'test': {}
254
+ });
255
+ const userError = new MyUserError('test', { msg: 'hello' }, '测试');
256
+ const systemError = new MySystemError('test', { msg: 'world' }, '测试');
257
+ // 基类的 is 方法应该能识别 define 创建的子类实例
258
+ expect(UserError.is(userError)).toBe(true);
259
+ expect(SystemError.is(systemError)).toBe(true);
260
+ // 但不会互相匹配
261
+ expect(UserError.is(systemError)).toBe(false);
262
+ expect(SystemError.is(userError)).toBe(false);
263
+ });
227
264
  });
228
265
  describe('泛型类型支持', () => {
229
266
  it('UserError应该支持字符串字面量类型', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taicode/common-base",
3
- "version": "1.7.5",
3
+ "version": "3.0.1",
4
4
  "author": "Alain",
5
5
  "license": "ISC",
6
6
  "description": "",