1 | | | import '_builtin_exceptions.dart'; |
2 | | | import 'squadron_error.dart'; |
3 | | | import 'squadron_exception.dart'; |
4 | | | import 'worker_exception.dart'; |
5 | | |
|
6 | | | typedef WorkerExceptionDeserializer = WorkerException? Function(List props); |
7 | | |
|
8 | | | class ExceptionManager { |
9 | | 11 | ExceptionManager(); |
10 | | |
|
11 | | | final _deserializers = Map.from(builtinExceptions); |
12 | | |
|
13 | | | /// Registers a deserializer for a custom [WorkerException]. If the deserializer is |
14 | | | /// already registered, registering it again will have no effect. |
15 | | 2 | void register( |
16 | | | String exceptionTypeId, WorkerExceptionDeserializer deserializer) { |
17 | | 4 | if (builtinExceptions.containsKey(exceptionTypeId)) { |
18 | | 0 | throw SquadronErrorImpl.create( |
19 | | 0 | 'Invalid exception type ID: $exceptionTypeId is reserved.', |
20 | | | ); |
21 | | | } |
22 | | 4 | _deserializers[exceptionTypeId] = deserializer; |
23 | | | } |
24 | | |
|
25 | | | /// Unregisters a deserializer that was previously registered, does nothing otherwise. |
26 | | | /// Please note that for a deregistration to have an effect, the exact same instance that |
27 | | | /// was provided to [register] must be provided to this method; avoid passing lambdas, |
28 | | | /// prefer passing static methods or top-level functions instead. |
29 | | 2 | void unregister(String exceptionTypeId) { |
30 | | 4 | if (builtinExceptions.containsKey(exceptionTypeId)) { |
31 | | 0 | throw SquadronErrorImpl.create( |
32 | | 0 | 'Invalid exception type ID: $exceptionTypeId is reserved.', |
33 | | | ); |
34 | | | } |
35 | | 4 | _deserializers.remove(exceptionTypeId); |
36 | | | } |
37 | | |
|
38 | | | /// Deserializes a [List] that was produced by [serialize]. |
39 | | 10 | SquadronException? deserialize(List? data) { |
40 | | 5 | if (data == null || data.isEmpty) { |
41 | | | return null; |
42 | | | } |
43 | | | try { |
44 | | 5 | final exceptionType = data[0]; |
45 | | 10 | final deserializer = _deserializers[exceptionType]; |
46 | | 5 | return deserializer?.call(data) ?? |
47 | | 2 | WorkerException( |
48 | | 2 | 'Failed to deserialize exception information for $exceptionType', |
49 | | | ); |
50 | | | } catch (ex, st) { |
51 | | 0 | return SquadronException.from(ex, st); |
52 | | | } |
53 | | | } |
54 | | | } |