@taicode/common-base 1.7.4 → 1.7.6
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/output/error/error.d.ts +110 -67
- package/output/error/error.d.ts.map +1 -1
- package/output/error/error.js +109 -61
- package/output/error/error.test.d.ts +0 -17
- package/output/error/error.test.d.ts.map +1 -1
- package/output/error/error.test.js +209 -99
- package/output/error/index.d.ts +2 -1
- package/output/error/index.d.ts.map +1 -1
- package/output/error/index.js +1 -1
- package/output/events/disposer.d.ts +6 -0
- package/output/events/disposer.d.ts.map +1 -0
- package/output/events/disposer.js +19 -0
- package/output/events/disposer.test.d.ts +2 -0
- package/output/events/disposer.test.d.ts.map +1 -0
- package/output/events/disposer.test.js +192 -0
- package/output/events/event-emitter.d.ts +33 -0
- package/output/events/event-emitter.d.ts.map +1 -0
- package/output/events/event-emitter.js +66 -0
- package/output/events/event-emitter.test.d.ts +2 -0
- package/output/events/event-emitter.test.d.ts.map +1 -0
- package/output/events/event-emitter.test.js +213 -0
- package/output/events/index.d.ts +3 -0
- package/output/events/index.d.ts.map +1 -0
- package/output/events/index.js +3 -0
- package/output/logger/formatter.d.ts +0 -1
- package/output/logger/formatter.d.ts.map +1 -1
- package/output/logger/formatter.js +1 -17
- package/output/logger/formatter.test.d.ts +0 -24
- package/output/logger/formatter.test.d.ts.map +1 -1
- package/output/logger/formatter.test.js +11 -30
- package/output/logger/logger.test.d.ts +0 -19
- package/output/logger/logger.test.d.ts.map +1 -1
- package/output/logger/logger.test.js +6 -16
- package/package.json +3 -2
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { UserError, SystemError
|
|
2
|
+
import { UserError, SystemError } from './error';
|
|
3
3
|
describe('UserError', () => {
|
|
4
4
|
describe('constructor', () => {
|
|
5
5
|
it('应该正确创建UserError实例', () => {
|
|
6
6
|
const type = 'VALIDATION_ERROR';
|
|
7
7
|
const message = '输入验证失败';
|
|
8
|
-
const error = new UserError(type, message);
|
|
8
|
+
const error = new UserError(type, undefined, message);
|
|
9
9
|
expect(error).toBeInstanceOf(Error);
|
|
10
10
|
expect(error).toBeInstanceOf(UserError);
|
|
11
11
|
expect(error.name).toBe('UserError');
|
|
@@ -32,7 +32,7 @@ describe('UserError', () => {
|
|
|
32
32
|
});
|
|
33
33
|
it('应该在提供空字符串message时保持空字符串', () => {
|
|
34
34
|
const type = 'VALIDATION_ERROR';
|
|
35
|
-
const error = new UserError(type, '');
|
|
35
|
+
const error = new UserError(type, {}, '');
|
|
36
36
|
expect(error).toBeInstanceOf(Error);
|
|
37
37
|
expect(error).toBeInstanceOf(UserError);
|
|
38
38
|
expect(error.name).toBe('UserError');
|
|
@@ -43,34 +43,32 @@ describe('UserError', () => {
|
|
|
43
43
|
const type = 'VALIDATION_ERROR';
|
|
44
44
|
const message = '输入验证失败';
|
|
45
45
|
const cause = new Error('原始错误');
|
|
46
|
-
const error = new UserError(type,
|
|
46
|
+
const error = new UserError(type, { cause }, message);
|
|
47
47
|
expect(error.cause).toBe(cause);
|
|
48
48
|
});
|
|
49
49
|
it('应该支持ErrorOptions参数且message为可选', () => {
|
|
50
50
|
const type = 'VALIDATION_ERROR';
|
|
51
51
|
const cause = new Error('原始错误');
|
|
52
|
-
const error = new UserError(type,
|
|
52
|
+
const error = new UserError(type, { cause });
|
|
53
53
|
expect(error.cause).toBe(cause);
|
|
54
54
|
expect(error.message).toBe('');
|
|
55
55
|
});
|
|
56
56
|
it('应该正确设置错误堆栈信息', () => {
|
|
57
|
-
const error = new UserError('TEST_ERROR', '测试错误');
|
|
57
|
+
const error = new UserError('TEST_ERROR', undefined, '测试错误');
|
|
58
58
|
expect(error.stack).toBeDefined();
|
|
59
59
|
expect(error.stack).toContain('UserError');
|
|
60
60
|
});
|
|
61
61
|
});
|
|
62
62
|
describe('is', () => {
|
|
63
63
|
it('应该正确识别UserError实例', () => {
|
|
64
|
-
const error = new UserError('TEST_ERROR', '测试错误');
|
|
64
|
+
const error = new UserError('TEST_ERROR', undefined, '测试错误');
|
|
65
65
|
expect(UserError.is(error)).toBe(true);
|
|
66
66
|
});
|
|
67
67
|
it('应该正确识别非UserError实例', () => {
|
|
68
68
|
const regularError = new Error('普通错误');
|
|
69
|
-
const systemError = new SystemError('SYSTEM_ERROR', '系统错误');
|
|
70
|
-
const unknownError = new UnknownError('未知错误');
|
|
69
|
+
const systemError = new SystemError('SYSTEM_ERROR', undefined, '系统错误');
|
|
71
70
|
expect(UserError.is(regularError)).toBe(false);
|
|
72
71
|
expect(UserError.is(systemError)).toBe(false);
|
|
73
|
-
expect(UserError.is(unknownError)).toBe(false);
|
|
74
72
|
expect(UserError.is(null)).toBe(false);
|
|
75
73
|
expect(UserError.is(undefined)).toBe(false);
|
|
76
74
|
expect(UserError.is('字符串')).toBe(false);
|
|
@@ -78,7 +76,7 @@ describe('UserError', () => {
|
|
|
78
76
|
expect(UserError.is({})).toBe(false);
|
|
79
77
|
});
|
|
80
78
|
it('应该支持类型守卫功能', () => {
|
|
81
|
-
const error = new UserError('TEST_ERROR', '测试错误');
|
|
79
|
+
const error = new UserError('TEST_ERROR', undefined, '测试错误');
|
|
82
80
|
if (UserError.is(error)) {
|
|
83
81
|
// 在类型守卫内部,error的类型应该被正确推断
|
|
84
82
|
expect(error.type).toBe('TEST_ERROR');
|
|
@@ -86,16 +84,27 @@ describe('UserError', () => {
|
|
|
86
84
|
expect(error.name).toBe('UserError');
|
|
87
85
|
}
|
|
88
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
|
+
});
|
|
89
98
|
});
|
|
90
99
|
describe('继承行为', () => {
|
|
91
100
|
it('应该正确继承Error的所有属性和方法', () => {
|
|
92
|
-
const error = new UserError('TEST_ERROR', '测试错误');
|
|
101
|
+
const error = new UserError('TEST_ERROR', undefined, '测试错误');
|
|
93
102
|
expect(error.toString()).toContain('测试错误');
|
|
94
103
|
expect(error.toString()).toContain('UserError');
|
|
95
104
|
expect(error instanceof Error).toBe(true);
|
|
96
105
|
});
|
|
97
106
|
it('应该支持Error的标准用法', () => {
|
|
98
|
-
const error = new UserError('TEST_ERROR', '测试错误');
|
|
107
|
+
const error = new UserError('TEST_ERROR', undefined, '测试错误');
|
|
99
108
|
try {
|
|
100
109
|
throw error;
|
|
101
110
|
}
|
|
@@ -111,7 +120,7 @@ describe('SystemError', () => {
|
|
|
111
120
|
it('应该正确创建SystemError实例', () => {
|
|
112
121
|
const type = 'DATABASE_ERROR';
|
|
113
122
|
const message = '数据库连接失败';
|
|
114
|
-
const error = new SystemError(type, message);
|
|
123
|
+
const error = new SystemError(type, undefined, message);
|
|
115
124
|
expect(error).toBeInstanceOf(Error);
|
|
116
125
|
expect(error).toBeInstanceOf(SystemError);
|
|
117
126
|
expect(error.name).toBe('SystemError');
|
|
@@ -138,7 +147,7 @@ describe('SystemError', () => {
|
|
|
138
147
|
});
|
|
139
148
|
it('应该在提供空字符串message时保持空字符串', () => {
|
|
140
149
|
const type = 'DATABASE_ERROR';
|
|
141
|
-
const error = new SystemError(type, '');
|
|
150
|
+
const error = new SystemError(type, {}, '');
|
|
142
151
|
expect(error).toBeInstanceOf(Error);
|
|
143
152
|
expect(error).toBeInstanceOf(SystemError);
|
|
144
153
|
expect(error.name).toBe('SystemError');
|
|
@@ -149,34 +158,32 @@ describe('SystemError', () => {
|
|
|
149
158
|
const type = 'NETWORK_ERROR';
|
|
150
159
|
const message = '网络请求失败';
|
|
151
160
|
const cause = new Error('连接超时');
|
|
152
|
-
const error = new SystemError(type,
|
|
161
|
+
const error = new SystemError(type, { cause }, message);
|
|
153
162
|
expect(error.cause).toBe(cause);
|
|
154
163
|
});
|
|
155
164
|
it('应该支持ErrorOptions参数且message为可选', () => {
|
|
156
165
|
const type = 'NETWORK_ERROR';
|
|
157
166
|
const cause = new Error('连接超时');
|
|
158
|
-
const error = new SystemError(type,
|
|
167
|
+
const error = new SystemError(type, { cause });
|
|
159
168
|
expect(error.cause).toBe(cause);
|
|
160
169
|
expect(error.message).toBe('');
|
|
161
170
|
});
|
|
162
171
|
it('应该正确设置错误堆栈信息', () => {
|
|
163
|
-
const error = new SystemError('FILE_ERROR', '文件读取失败');
|
|
172
|
+
const error = new SystemError('FILE_ERROR', undefined, '文件读取失败');
|
|
164
173
|
expect(error.stack).toBeDefined();
|
|
165
174
|
expect(error.stack).toContain('SystemError');
|
|
166
175
|
});
|
|
167
176
|
});
|
|
168
177
|
describe('is', () => {
|
|
169
178
|
it('应该正确识别SystemError实例', () => {
|
|
170
|
-
const error = new SystemError('TEST_ERROR', '测试错误');
|
|
179
|
+
const error = new SystemError('TEST_ERROR', undefined, '测试错误');
|
|
171
180
|
expect(SystemError.is(error)).toBe(true);
|
|
172
181
|
});
|
|
173
182
|
it('应该正确识别非SystemError实例', () => {
|
|
174
183
|
const regularError = new Error('普通错误');
|
|
175
|
-
const userError = new UserError('USER_ERROR', '用户错误');
|
|
176
|
-
const unknownError = new UnknownError('未知错误');
|
|
184
|
+
const userError = new UserError('USER_ERROR', undefined, '用户错误');
|
|
177
185
|
expect(SystemError.is(regularError)).toBe(false);
|
|
178
186
|
expect(SystemError.is(userError)).toBe(false);
|
|
179
|
-
expect(SystemError.is(unknownError)).toBe(false);
|
|
180
187
|
expect(SystemError.is(null)).toBe(false);
|
|
181
188
|
expect(SystemError.is(undefined)).toBe(false);
|
|
182
189
|
expect(SystemError.is('字符串')).toBe(false);
|
|
@@ -184,7 +191,7 @@ describe('SystemError', () => {
|
|
|
184
191
|
expect(SystemError.is({})).toBe(false);
|
|
185
192
|
});
|
|
186
193
|
it('应该支持类型守卫功能', () => {
|
|
187
|
-
const error = new SystemError('DATABASE_ERROR', '数据库错误');
|
|
194
|
+
const error = new SystemError('DATABASE_ERROR', undefined, '数据库错误');
|
|
188
195
|
if (SystemError.is(error)) {
|
|
189
196
|
// 在类型守卫内部,error的类型应该被正确推断
|
|
190
197
|
expect(error.type).toBe('DATABASE_ERROR');
|
|
@@ -192,16 +199,26 @@ describe('SystemError', () => {
|
|
|
192
199
|
expect(error.name).toBe('SystemError');
|
|
193
200
|
}
|
|
194
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
|
+
});
|
|
195
212
|
});
|
|
196
213
|
describe('继承行为', () => {
|
|
197
214
|
it('应该正确继承Error的所有属性和方法', () => {
|
|
198
|
-
const error = new SystemError('TEST_ERROR', '测试错误');
|
|
215
|
+
const error = new SystemError('TEST_ERROR', undefined, '测试错误');
|
|
199
216
|
expect(error.toString()).toContain('测试错误');
|
|
200
217
|
expect(error.toString()).toContain('SystemError');
|
|
201
218
|
expect(error instanceof Error).toBe(true);
|
|
202
219
|
});
|
|
203
220
|
it('应该支持Error的标准用法', () => {
|
|
204
|
-
const error = new SystemError('TEST_ERROR', '测试错误');
|
|
221
|
+
const error = new SystemError('TEST_ERROR', undefined, '测试错误');
|
|
205
222
|
try {
|
|
206
223
|
throw error;
|
|
207
224
|
}
|
|
@@ -212,99 +229,192 @@ describe('SystemError', () => {
|
|
|
212
229
|
});
|
|
213
230
|
});
|
|
214
231
|
});
|
|
215
|
-
describe('UnknownError', () => {
|
|
216
|
-
describe('constructor', () => {
|
|
217
|
-
it('应该正确创建UnknownError实例', () => {
|
|
218
|
-
const message = '发生了未知错误';
|
|
219
|
-
const error = new UnknownError(message);
|
|
220
|
-
expect(error).toBeInstanceOf(Error);
|
|
221
|
-
expect(error).toBeInstanceOf(UnknownError);
|
|
222
|
-
expect(error.name).toBe('UnknownError');
|
|
223
|
-
expect(error.message).toBe(message);
|
|
224
|
-
});
|
|
225
|
-
it('应该支持ErrorOptions参数', () => {
|
|
226
|
-
const message = '未知错误';
|
|
227
|
-
const cause = new Error('原始未知错误');
|
|
228
|
-
const error = new UnknownError(message, { cause });
|
|
229
|
-
expect(error.cause).toBe(cause);
|
|
230
|
-
});
|
|
231
|
-
it('应该正确设置错误堆栈信息', () => {
|
|
232
|
-
const error = new UnknownError('测试未知错误');
|
|
233
|
-
expect(error.stack).toBeDefined();
|
|
234
|
-
expect(error.stack).toContain('UnknownError');
|
|
235
|
-
});
|
|
236
|
-
});
|
|
237
|
-
describe('is', () => {
|
|
238
|
-
it('应该正确识别UnknownError实例', () => {
|
|
239
|
-
const error = new UnknownError('测试错误');
|
|
240
|
-
expect(UnknownError.is(error)).toBe(true);
|
|
241
|
-
});
|
|
242
|
-
it('应该正确识别非UnknownError实例', () => {
|
|
243
|
-
const regularError = new Error('普通错误');
|
|
244
|
-
const userError = new UserError('USER_ERROR', '用户错误');
|
|
245
|
-
const systemError = new SystemError('SYSTEM_ERROR', '系统错误');
|
|
246
|
-
expect(UnknownError.is(regularError)).toBe(false);
|
|
247
|
-
expect(UnknownError.is(userError)).toBe(false);
|
|
248
|
-
expect(UnknownError.is(systemError)).toBe(false);
|
|
249
|
-
expect(UnknownError.is(null)).toBe(false);
|
|
250
|
-
expect(UnknownError.is(undefined)).toBe(false);
|
|
251
|
-
expect(UnknownError.is('字符串')).toBe(false);
|
|
252
|
-
expect(UnknownError.is(123)).toBe(false);
|
|
253
|
-
expect(UnknownError.is({})).toBe(false);
|
|
254
|
-
});
|
|
255
|
-
});
|
|
256
|
-
describe('继承行为', () => {
|
|
257
|
-
it('应该正确继承Error的所有属性和方法', () => {
|
|
258
|
-
const error = new UnknownError('测试错误');
|
|
259
|
-
expect(error.toString()).toContain('测试错误');
|
|
260
|
-
expect(error instanceof Error).toBe(true);
|
|
261
|
-
});
|
|
262
|
-
it('应该支持Error的标准用法', () => {
|
|
263
|
-
const error = new UnknownError('测试错误');
|
|
264
|
-
try {
|
|
265
|
-
throw error;
|
|
266
|
-
}
|
|
267
|
-
catch (caught) {
|
|
268
|
-
expect(caught).toBe(error);
|
|
269
|
-
expect(caught).toBeInstanceOf(UnknownError);
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
});
|
|
274
232
|
describe('错误类型区分', () => {
|
|
275
|
-
it('
|
|
276
|
-
const userError = new UserError('USER_ERROR', '用户错误');
|
|
277
|
-
const systemError = new SystemError('SYSTEM_ERROR', '系统错误');
|
|
278
|
-
const unknownError = new UnknownError('未知错误');
|
|
233
|
+
it('两种错误类型应该是不同的类', () => {
|
|
234
|
+
const userError = new UserError('USER_ERROR', undefined, '用户错误');
|
|
235
|
+
const systemError = new SystemError('SYSTEM_ERROR', undefined, '系统错误');
|
|
279
236
|
// 每种错误只能被自己的类型检查函数识别
|
|
280
237
|
expect(UserError.is(userError)).toBe(true);
|
|
281
238
|
expect(SystemError.is(userError)).toBe(false);
|
|
282
|
-
expect(UnknownError.is(userError)).toBe(false);
|
|
283
239
|
expect(UserError.is(systemError)).toBe(false);
|
|
284
240
|
expect(SystemError.is(systemError)).toBe(true);
|
|
285
|
-
expect(UnknownError.is(systemError)).toBe(false);
|
|
286
|
-
expect(UserError.is(unknownError)).toBe(false);
|
|
287
|
-
expect(SystemError.is(unknownError)).toBe(false);
|
|
288
|
-
expect(UnknownError.is(unknownError)).toBe(true);
|
|
289
241
|
});
|
|
290
242
|
it('所有错误类型都应该是Error的实例', () => {
|
|
291
|
-
const userError = new UserError('USER_ERROR', '用户错误');
|
|
292
|
-
const systemError = new SystemError('SYSTEM_ERROR', '系统错误');
|
|
293
|
-
const unknownError = new UnknownError('未知错误');
|
|
243
|
+
const userError = new UserError('USER_ERROR', undefined, '用户错误');
|
|
244
|
+
const systemError = new SystemError('SYSTEM_ERROR', undefined, '系统错误');
|
|
294
245
|
expect(userError instanceof Error).toBe(true);
|
|
295
246
|
expect(systemError instanceof Error).toBe(true);
|
|
296
|
-
|
|
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);
|
|
297
263
|
});
|
|
298
264
|
});
|
|
299
265
|
describe('泛型类型支持', () => {
|
|
300
266
|
it('UserError应该支持字符串字面量类型', () => {
|
|
301
|
-
const error = new UserError('REQUIRED_FIELD', '字段必填');
|
|
267
|
+
const error = new UserError('REQUIRED_FIELD', {}, '字段必填');
|
|
302
268
|
expect(error.type).toBe('REQUIRED_FIELD');
|
|
303
269
|
expect(UserError.is(error)).toBe(true);
|
|
304
270
|
});
|
|
305
271
|
it('SystemError应该支持字符串字面量类型', () => {
|
|
306
|
-
const error = new SystemError('DATABASE_ERROR', '数据库连接失败');
|
|
272
|
+
const error = new SystemError('DATABASE_ERROR', {}, '数据库连接失败');
|
|
307
273
|
expect(error.type).toBe('DATABASE_ERROR');
|
|
308
274
|
expect(SystemError.is(error)).toBe(true);
|
|
309
275
|
});
|
|
310
276
|
});
|
|
277
|
+
describe('define 工厂方法', () => {
|
|
278
|
+
describe('UserError.define', () => {
|
|
279
|
+
it('应该定义一个绑定了特定错误类型的 UserError 类', () => {
|
|
280
|
+
const MyUserError = UserError.define({
|
|
281
|
+
'validation-failed': {},
|
|
282
|
+
'permission-denied': {},
|
|
283
|
+
'not-found': {}
|
|
284
|
+
});
|
|
285
|
+
const error = new MyUserError('validation-failed', {
|
|
286
|
+
field: 'email',
|
|
287
|
+
value: 'invalid@'
|
|
288
|
+
}, '验证失败');
|
|
289
|
+
expect(error).toBeInstanceOf(Error);
|
|
290
|
+
expect(error.name).toBe('UserError');
|
|
291
|
+
expect(error.type).toBe('validation-failed');
|
|
292
|
+
expect(error.message).toBe('验证失败');
|
|
293
|
+
expect(error.context).toEqual({ field: 'email', value: 'invalid@' });
|
|
294
|
+
});
|
|
295
|
+
it('应该支持 is 类型守卫', () => {
|
|
296
|
+
const MyUserError = UserError.define({
|
|
297
|
+
'test-error': {}
|
|
298
|
+
});
|
|
299
|
+
const error = new MyUserError('test-error', { code: 123 }, '测试错误');
|
|
300
|
+
expect(MyUserError.is(error)).toBe(true);
|
|
301
|
+
expect(MyUserError.is(new Error('普通错误'))).toBe(false);
|
|
302
|
+
expect(MyUserError.is(null)).toBe(false);
|
|
303
|
+
});
|
|
304
|
+
it('应该支持多次调用 define 定义不同的错误类', () => {
|
|
305
|
+
const ValidationError = UserError.define({
|
|
306
|
+
'required': {},
|
|
307
|
+
'invalid': {}
|
|
308
|
+
});
|
|
309
|
+
const AuthError = UserError.define({
|
|
310
|
+
'unauthorized': {},
|
|
311
|
+
'forbidden': {}
|
|
312
|
+
});
|
|
313
|
+
const validationError = new ValidationError('required', { field: 'username' }, '必填字段');
|
|
314
|
+
const authError = new AuthError('unauthorized', { reason: 'token expired' }, '未授权');
|
|
315
|
+
expect(validationError.type).toBe('required');
|
|
316
|
+
expect(authError.type).toBe('unauthorized');
|
|
317
|
+
expect(ValidationError.is(validationError)).toBe(true);
|
|
318
|
+
expect(ValidationError.is(authError)).toBe(false); // 不同的类不会互相识别
|
|
319
|
+
expect(AuthError.is(authError)).toBe(true);
|
|
320
|
+
expect(AuthError.is(validationError)).toBe(false); // 不同的类不会互相识别
|
|
321
|
+
});
|
|
322
|
+
it('应该支持不传 context 参数', () => {
|
|
323
|
+
const MyUserError = UserError.define({
|
|
324
|
+
'simple-error': {}
|
|
325
|
+
});
|
|
326
|
+
const error = new MyUserError('simple-error', undefined, '简单错误');
|
|
327
|
+
expect(error.type).toBe('simple-error');
|
|
328
|
+
expect(error.message).toBe('简单错误');
|
|
329
|
+
expect(error.context).toBeUndefined();
|
|
330
|
+
});
|
|
331
|
+
it('应该支持不传 message 参数', () => {
|
|
332
|
+
const MyUserError = UserError.define({
|
|
333
|
+
'no-message': {}
|
|
334
|
+
});
|
|
335
|
+
const error = new MyUserError('no-message');
|
|
336
|
+
expect(error.type).toBe('no-message');
|
|
337
|
+
expect(error.message).toBe('');
|
|
338
|
+
});
|
|
339
|
+
it('应该暴露所有定义的错误类型', () => {
|
|
340
|
+
const MyUserError = UserError.define({
|
|
341
|
+
'validation-failed': {},
|
|
342
|
+
'permission-denied': {},
|
|
343
|
+
'not-found': {}
|
|
344
|
+
});
|
|
345
|
+
expect(MyUserError.types).toEqual(['validation-failed', 'permission-denied', 'not-found']);
|
|
346
|
+
expect(MyUserError.types).toHaveLength(3);
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
describe('SystemError.define', () => {
|
|
350
|
+
it('应该定义一个绑定了特定错误类型的 SystemError 类', () => {
|
|
351
|
+
const MySystemError = SystemError.define({
|
|
352
|
+
'database-error': {},
|
|
353
|
+
'network-error': {},
|
|
354
|
+
'service-unavailable': {}
|
|
355
|
+
});
|
|
356
|
+
const error = new MySystemError('database-error', {
|
|
357
|
+
query: 'SELECT * FROM users',
|
|
358
|
+
table: 'users'
|
|
359
|
+
}, '数据库错误');
|
|
360
|
+
expect(error).toBeInstanceOf(Error);
|
|
361
|
+
expect(error.name).toBe('SystemError');
|
|
362
|
+
expect(error.type).toBe('database-error');
|
|
363
|
+
expect(error.message).toBe('数据库错误');
|
|
364
|
+
expect(error.context).toEqual({ query: 'SELECT * FROM users', table: 'users' });
|
|
365
|
+
});
|
|
366
|
+
it('应该支持 is 类型守卫', () => {
|
|
367
|
+
const MySystemError = SystemError.define({
|
|
368
|
+
'test-error': {}
|
|
369
|
+
});
|
|
370
|
+
const error = new MySystemError('test-error', { code: 500 }, '测试错误');
|
|
371
|
+
expect(MySystemError.is(error)).toBe(true);
|
|
372
|
+
expect(MySystemError.is(new Error('普通错误'))).toBe(false);
|
|
373
|
+
expect(MySystemError.is(null)).toBe(false);
|
|
374
|
+
});
|
|
375
|
+
it('应该支持多次调用 define 定义不同的错误类', () => {
|
|
376
|
+
const DatabaseError = SystemError.define({
|
|
377
|
+
'connection-failed': {},
|
|
378
|
+
'query-timeout': {}
|
|
379
|
+
});
|
|
380
|
+
const NetworkError = SystemError.define({
|
|
381
|
+
'request-failed': {},
|
|
382
|
+
'timeout': {}
|
|
383
|
+
});
|
|
384
|
+
const dbError = new DatabaseError('connection-failed', { host: 'localhost', port: 5432 }, '连接失败');
|
|
385
|
+
const netError = new NetworkError('request-failed', { url: '/api/data', method: 'GET' }, '请求失败');
|
|
386
|
+
expect(dbError.type).toBe('connection-failed');
|
|
387
|
+
expect(netError.type).toBe('request-failed');
|
|
388
|
+
expect(DatabaseError.is(dbError)).toBe(true);
|
|
389
|
+
expect(DatabaseError.is(netError)).toBe(false); // 不同的类不会互相识别
|
|
390
|
+
expect(NetworkError.is(netError)).toBe(true);
|
|
391
|
+
expect(NetworkError.is(dbError)).toBe(false); // 不同的类不会互相识别
|
|
392
|
+
});
|
|
393
|
+
it('应该支持不传 context 参数', () => {
|
|
394
|
+
const MySystemError = SystemError.define({
|
|
395
|
+
'simple-error': {}
|
|
396
|
+
});
|
|
397
|
+
const error = new MySystemError('simple-error', undefined, '简单错误');
|
|
398
|
+
expect(error.type).toBe('simple-error');
|
|
399
|
+
expect(error.message).toBe('简单错误');
|
|
400
|
+
expect(error.context).toBeUndefined();
|
|
401
|
+
});
|
|
402
|
+
it('应该支持不传 message 参数', () => {
|
|
403
|
+
const MySystemError = SystemError.define({
|
|
404
|
+
'no-message': {}
|
|
405
|
+
});
|
|
406
|
+
const error = new MySystemError('no-message');
|
|
407
|
+
expect(error.type).toBe('no-message');
|
|
408
|
+
expect(error.message).toBe('');
|
|
409
|
+
});
|
|
410
|
+
it('应该暴露所有定义的错误类型', () => {
|
|
411
|
+
const MySystemError = SystemError.define({
|
|
412
|
+
'database-error': {},
|
|
413
|
+
'network-error': {},
|
|
414
|
+
'service-unavailable': {}
|
|
415
|
+
});
|
|
416
|
+
expect(MySystemError.types).toEqual(['database-error', 'network-error', 'service-unavailable']);
|
|
417
|
+
expect(MySystemError.types).toHaveLength(3);
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
});
|
package/output/error/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export { UserError, SystemError
|
|
1
|
+
export { UserError, SystemError } from './error';
|
|
2
|
+
export type { ErrorContext } from './error';
|
|
2
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/error/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/error/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,WAAW,EACZ,MAAM,SAAS,CAAA;AAEhB,YAAY,EACV,YAAY,EACb,MAAM,SAAS,CAAA"}
|
package/output/error/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { UserError, SystemError
|
|
1
|
+
export { UserError, SystemError } from './error';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"disposer.d.ts","sourceRoot":"","sources":["../../source/events/disposer.ts"],"names":[],"mappings":"AAAA,qBAAa,QAAQ;IACnB,OAAO,CAAC,gBAAgB,CAAyB;IAGjD,WAAW,CAAC,SAAS,EAAE,MAAM,OAAO,GAAG,IAAI;IAK3C,OAAO,IAAI,IAAI;CAUhB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export class Disposer {
|
|
2
|
+
cleanupFunctions = [];
|
|
3
|
+
// 添加清理函数
|
|
4
|
+
addDisposer(cleanupFn) {
|
|
5
|
+
this.cleanupFunctions.push(cleanupFn);
|
|
6
|
+
}
|
|
7
|
+
// 执行所有清理函数
|
|
8
|
+
dispose() {
|
|
9
|
+
for (const cleanupFn of this.cleanupFunctions) {
|
|
10
|
+
try {
|
|
11
|
+
cleanupFn();
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
console.error('Error during cleanup:', error);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
this.cleanupFunctions = []; // 清空清理函数列表
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"disposer.test.d.ts","sourceRoot":"","sources":["../../source/events/disposer.test.ts"],"names":[],"mappings":""}
|