class ApiException implements Exception { const ApiException({ this.statusCode, required this.message, this.retryAfterSeconds, }); final int? statusCode; final String message; final int? retryAfterSeconds; bool get isUnauthorized => statusCode == 401; @override String toString() => message; static ApiException fromBody({ int? statusCode, Object? body, String fallback = 'Something went wrong.', }) { var message = fallback; int? retryAfterSeconds; if (body is Map) { final error = body['error']; if (error is String && error.trim().isNotEmpty) { message = error.trim(); } final retry = body['retryAfterSeconds']; if (retry is int) { retryAfterSeconds = retry; } else if (retry is num) { retryAfterSeconds = retry.toInt(); } } if (retryAfterSeconds != null) { message = '$message Retry after $retryAfterSeconds seconds.'; } return ApiException( statusCode: statusCode, message: message, retryAfterSeconds: retryAfterSeconds, ); } }