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