| 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 | | | } |