| 1 | | | import 'dart:async'; |
| 2 | | | import 'dart:convert'; |
| 3 | | | |
| 4 | | | import 'package:cancelation_token/cancelation_token.dart'; |
| 5 | | | |
| 6 | | | import '_builtin_exceptions.dart'; |
| 7 | | | import 'worker_exception.dart'; |
| 8 | | | |
| 9 | | | /// Base abstract class for exceptions in Squadron. |
| 10 | | | abstract class SquadronException implements Exception { |
| 11 | | 12 | SquadronException.init(this.message, [this._stackTrace]) { |
| 12 | | 12 | if (_stackTrace == null) { |
| 13 | | | try { |
| 14 | | 24 | _stackTrace = StackTrace.current; |
| 15 | | | } catch (_, st) { |
| 16 | | | // failed, take the opportunity to get the stack trace from this exception! |
| 17 | | 0 | _stackTrace = st; |
| 18 | | | } |
| 19 | | | } |
| 20 | | | } |
| 21 | | | |
| 22 | | | /// This method returns [error] if it is a [SquadronException] (enriching it |
| 23 | | | /// with [command] if it is a [WorkerException]). Otherwise, it returns a new |
| 24 | | | /// [WorkerException] wrapping [error] and [stackTrace]. |
| 25 | | 8 | static SquadronException from(Object error, |
| 26 | | | [StackTrace? stackTrace, int? command]) { |
| 27 | | 8 | if (error is WorkerException) { |
| 28 | | 4 | if (command != null) error.setCommand(command); |
| 29 | | | return error; |
| 30 | | 7 | } else if (error is SquadronException) { |
| 31 | | | return error; |
| 32 | | 4 | } else if (error is CanceledException) { |
| 33 | | 2 | return error.toSquadronException(); |
| 34 | | 4 | } else if (error is TimeoutException) { |
| 35 | | 2 | return error.toSquadronException(); |
| 36 | | | } else { |
| 37 | | 8 | return WorkerException(error.toString(), stackTrace, command); |
| 38 | | | } |
| 39 | | | } |
| 40 | | | |
| 41 | | | final String message; |
| 42 | | | |
| 43 | | | /// The exception's [StackTrace]. |
| 44 | | 12 | StackTrace? get stackTrace => _stackTrace; |
| 45 | | | StackTrace? _stackTrace; |
| 46 | | | |
| 47 | | 2 | @override |
| 48 | | 4 | String toString() => jsonEncode(serialize()); |
| 49 | | | |
| 50 | | | /// Serializes the exception, i.e. returns a list of items that can cross thread boundaries. |
| 51 | | | List serialize(); |
| 52 | | | |
| 53 | | | /// Deserializes a [stackTrace] if any. Returns null if no [StackTrace] is provided. |
| 54 | | 10 | static StackTrace? loadStackTrace(String? stackTrace) { |
| 55 | | | if (stackTrace == null) return null; |
| 56 | | | try { |
| 57 | | 6 | return StackTrace.fromString(stackTrace); |
| 58 | | | } catch (_) { |
| 59 | | | return null; |
| 60 | | | } |
| 61 | | | } |
| 62 | | | } |