import 'package:dio/dio.dart'; import '../../errors/app_exception.dart'; import '../../errors/auth_exception.dart'; import '../../errors/network_exception.dart'; import '../../errors/parse_exception.dart'; import '../../errors/server_exception.dart'; /// The error code of a rejected call: the server answers either with JSON /// `{"error": ""}` or with the plain text `Fehler: ` of its /// generic error handler. String? marianumConnectErrorCode(Object? body) { if (body is Map) { final code = body['error']; return code is String ? code : null; } if (body is String) { const prefix = 'Fehler: '; return (body.startsWith(prefix) ? body.substring(prefix.length) : body) .trim(); } return null; } /// Converts a DioException raised against the Marianum-Connect API into one of /// the app's typed AppExceptions. Keeps the dio dependency out of call sites /// that just want to render an error message. AppException mapMarianumConnectError(DioException error) { switch (error.type) { case DioExceptionType.connectionTimeout: case DioExceptionType.sendTimeout: case DioExceptionType.receiveTimeout: case DioExceptionType.transformTimeout: return NetworkException.timeout(technicalDetails: error.message); case DioExceptionType.connectionError: return NetworkException(technicalDetails: error.message); case DioExceptionType.badCertificate: return const NetworkException( userMessage: 'Die sichere Verbindung zum Marianum-Connect-Server wurde abgelehnt.', ); case DioExceptionType.badResponse: final status = error.response?.statusCode ?? -1; if (status == 401) { return AuthException.unauthorized( technicalDetails: 'MC 401: ${error.response?.data}', ); } if (status == 403) { return AuthException.forbidden( technicalDetails: 'MC 403: ${error.response?.data}', ); } return ServerException( statusCode: status, technicalDetails: 'MC HTTP $status: ${error.response?.data}', ); case DioExceptionType.cancel: case DioExceptionType.unknown: final inner = error.error; if (inner is FormatException) { return ParseException(technicalDetails: inner.message); } return NetworkException(technicalDetails: error.message); } }