refactor: more logs
This commit is contained in:
@@ -1,14 +1,9 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart' hide debugPrint;
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'api_error.dart';
|
||||
import 'error_parser.dart';
|
||||
import '../utils/debug_logger.dart';
|
||||
|
||||
void debugPrint(String? message, {int? wrapWidth}) {
|
||||
if (message == null) return;
|
||||
DebugLogger.fromLegacy(message, scope: 'api/error-handler');
|
||||
}
|
||||
|
||||
/// Comprehensive API error handler with structured error parsing
|
||||
/// Handles all types of API errors and converts them to standardized format
|
||||
class ApiErrorHandler {
|
||||
@@ -39,7 +34,10 @@ class ApiErrorHandler {
|
||||
}
|
||||
} catch (e) {
|
||||
// Fallback error if transformation itself fails
|
||||
debugPrint('ApiErrorHandler: Error transforming exception: $e');
|
||||
DebugLogger.log(
|
||||
'ApiErrorHandler: Error transforming exception: $e',
|
||||
scope: 'api/error-handler',
|
||||
);
|
||||
return ApiError.unknown(
|
||||
message: 'A system error occurred',
|
||||
originalError: error,
|
||||
@@ -318,21 +316,33 @@ class ApiErrorHandler {
|
||||
String httpMethod,
|
||||
) {
|
||||
if (kDebugMode) {
|
||||
debugPrint('🔴 API Error Details:');
|
||||
debugPrint(' Method: ${httpMethod.toUpperCase()}');
|
||||
debugPrint(' Endpoint: $requestPath');
|
||||
debugPrint(' Type: ${dioError.type}');
|
||||
debugPrint(' Status: ${dioError.response?.statusCode}');
|
||||
DebugLogger.log('🔴 API Error Details:', scope: 'api/error-handler');
|
||||
DebugLogger.log(
|
||||
' Method: ${httpMethod.toUpperCase()}',
|
||||
scope: 'api/error-handler',
|
||||
);
|
||||
DebugLogger.log(' Endpoint: $requestPath', scope: 'api/error-handler');
|
||||
DebugLogger.log(' Type: ${dioError.type}', scope: 'api/error-handler');
|
||||
DebugLogger.log(
|
||||
' Status: ${dioError.response?.statusCode}',
|
||||
scope: 'api/error-handler',
|
||||
);
|
||||
|
||||
if (dioError.response?.data != null) {
|
||||
DebugLogger.error('Response data available (truncated for security)');
|
||||
}
|
||||
|
||||
if (dioError.requestOptions.data != null) {
|
||||
debugPrint(' Request Data: ${dioError.requestOptions.data}');
|
||||
DebugLogger.log(
|
||||
' Request Data: ${dioError.requestOptions.data}',
|
||||
scope: 'api/error-handler',
|
||||
);
|
||||
}
|
||||
|
||||
debugPrint(' Error: ${dioError.message}');
|
||||
DebugLogger.log(
|
||||
' Error: ${dioError.message}',
|
||||
scope: 'api/error-handler',
|
||||
);
|
||||
}
|
||||
|
||||
// In production, you would send this to your error tracking service
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart' hide debugPrint;
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'api_error_handler.dart';
|
||||
import 'api_error.dart';
|
||||
import '../utils/debug_logger.dart';
|
||||
|
||||
void debugPrint(String? message, {int? wrapWidth}) {
|
||||
if (message == null) return;
|
||||
DebugLogger.fromLegacy(message, scope: 'api/error-interceptor');
|
||||
}
|
||||
|
||||
/// Dio interceptor for automatic error handling and transformation
|
||||
/// Converts all HTTP errors into standardized ApiError format
|
||||
class ApiErrorInterceptor extends Interceptor {
|
||||
@@ -51,7 +46,11 @@ class ApiErrorInterceptor extends Interceptor {
|
||||
}
|
||||
} catch (e) {
|
||||
// Fallback if error transformation fails
|
||||
debugPrint('ApiErrorInterceptor: Failed to transform error: $e');
|
||||
DebugLogger.error(
|
||||
'transform-failed',
|
||||
scope: 'api/error-interceptor',
|
||||
error: e,
|
||||
);
|
||||
handler.next(err);
|
||||
}
|
||||
}
|
||||
@@ -71,7 +70,16 @@ class ApiErrorInterceptor extends Interceptor {
|
||||
);
|
||||
|
||||
if (logErrors) {
|
||||
debugPrint('🟡 API Error in successful response: $apiError');
|
||||
DebugLogger.warning(
|
||||
'successful-response-error',
|
||||
scope: 'api/error-interceptor',
|
||||
data: {
|
||||
'endpoint': apiError.endpoint,
|
||||
'method': apiError.method,
|
||||
'status': apiError.statusCode,
|
||||
'message': apiError.message,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Store the error for later handling
|
||||
@@ -122,74 +130,59 @@ class ApiErrorInterceptor extends Interceptor {
|
||||
void _logApiError(ApiError apiError, DioException originalError) {
|
||||
if (!kDebugMode) return;
|
||||
|
||||
final typeIcon = _getErrorTypeIcon(apiError.type);
|
||||
debugPrint('$typeIcon API Error [${apiError.type.name.toUpperCase()}]');
|
||||
debugPrint(' Method: ${apiError.method?.toUpperCase() ?? 'UNKNOWN'}');
|
||||
debugPrint(' Endpoint: ${apiError.endpoint ?? 'unknown'}');
|
||||
debugPrint(' Status: ${apiError.statusCode ?? 'N/A'}');
|
||||
debugPrint(' Message: ${apiError.message}');
|
||||
final payload = <String, Object?>{
|
||||
'type': apiError.type.name,
|
||||
'endpoint': apiError.endpoint,
|
||||
'method': apiError.method,
|
||||
'status': apiError.statusCode,
|
||||
'message': apiError.message,
|
||||
if (apiError.technical != null) 'technical': apiError.technical,
|
||||
if (apiError.retryAfter != null)
|
||||
'retryAfterSeconds': apiError.retryAfter!.inSeconds,
|
||||
'originalType': originalError.type.name,
|
||||
};
|
||||
|
||||
if (apiError.hasFieldErrors) {
|
||||
debugPrint(' Field Errors:');
|
||||
for (final entry in apiError.fieldErrors.entries) {
|
||||
final field = entry.key;
|
||||
final errors = entry.value;
|
||||
debugPrint(' $field: ${errors.join(', ')}');
|
||||
}
|
||||
payload['fieldErrors'] = {
|
||||
for (final entry in apiError.fieldErrors.entries)
|
||||
entry.key: entry.value,
|
||||
};
|
||||
}
|
||||
|
||||
if (apiError.technical != null) {
|
||||
debugPrint(' Technical: ${apiError.technical}');
|
||||
}
|
||||
|
||||
if (apiError.retryAfter != null) {
|
||||
debugPrint(' Retry After: ${apiError.retryAfter!.inSeconds}s');
|
||||
}
|
||||
|
||||
// Log original error type for debugging
|
||||
debugPrint(' Original Type: ${originalError.type}');
|
||||
|
||||
// Log request details if available
|
||||
final requestData = originalError.requestOptions.data;
|
||||
if (requestData != null && requestData.toString().length < 500) {
|
||||
debugPrint(' Request: $requestData');
|
||||
payload['request'] = requestData;
|
||||
}
|
||||
|
||||
// Log response data if available and not too large
|
||||
final responseData = originalError.response?.data;
|
||||
if (responseData != null && responseData.toString().length < 1000) {
|
||||
DebugLogger.error('Response data available (truncated for security)');
|
||||
payload['response'] = responseData;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get emoji icon for error type
|
||||
String _getErrorTypeIcon(ApiErrorType type) {
|
||||
switch (type) {
|
||||
case ApiErrorType.network:
|
||||
return '🌐';
|
||||
case ApiErrorType.timeout:
|
||||
return '⏱️';
|
||||
case ApiErrorType.authentication:
|
||||
return '🔐';
|
||||
case ApiErrorType.authorization:
|
||||
return '🚫';
|
||||
case ApiErrorType.validation:
|
||||
return '✏️';
|
||||
case ApiErrorType.badRequest:
|
||||
return '❌';
|
||||
case ApiErrorType.notFound:
|
||||
return '🔍';
|
||||
case ApiErrorType.server:
|
||||
return '🔥';
|
||||
case ApiErrorType.rateLimit:
|
||||
return '🐌';
|
||||
case ApiErrorType.cancelled:
|
||||
return '🛑';
|
||||
case ApiErrorType.security:
|
||||
return '🔒';
|
||||
case ApiErrorType.unknown:
|
||||
return '❓';
|
||||
final headers = originalError.requestOptions.headers;
|
||||
if (headers.isNotEmpty) {
|
||||
payload['requestHeaders'] = {
|
||||
for (final entry in headers.entries) entry.key: entry.value.toString(),
|
||||
};
|
||||
}
|
||||
|
||||
final responseHeaders = originalError.response?.headers;
|
||||
if (responseHeaders != null && responseHeaders.map.isNotEmpty) {
|
||||
payload['responseHeaders'] = responseHeaders.map;
|
||||
}
|
||||
|
||||
final requestDuration =
|
||||
originalError.response?.requestOptions.extra['requestDuration'];
|
||||
if (requestDuration is Duration) {
|
||||
payload['requestDurationMs'] = requestDuration.inMilliseconds;
|
||||
}
|
||||
|
||||
DebugLogger.error(
|
||||
'api-error',
|
||||
scope: 'api/error-interceptor',
|
||||
data: payload,
|
||||
error: apiError,
|
||||
);
|
||||
}
|
||||
|
||||
/// Extract ApiError from DioException if available
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart' hide debugPrint;
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'api_error.dart';
|
||||
import 'api_error_handler.dart';
|
||||
@@ -9,11 +9,6 @@ import '../../shared/theme/theme_extensions.dart';
|
||||
import 'package:conduit/l10n/app_localizations.dart';
|
||||
import '../utils/debug_logger.dart';
|
||||
|
||||
void debugPrint(String? message, {int? wrapWidth}) {
|
||||
if (message == null) return;
|
||||
DebugLogger.fromLegacy(message, scope: 'api/error-service');
|
||||
}
|
||||
|
||||
/// Enhanced error service with comprehensive error handling capabilities
|
||||
/// Provides unified error management across the application
|
||||
class EnhancedErrorService {
|
||||
@@ -306,16 +301,31 @@ class EnhancedErrorService {
|
||||
}) {
|
||||
if (kDebugMode) {
|
||||
final timestamp = DateTime.now().toIso8601String();
|
||||
debugPrint('🔴 ERROR [$timestamp] ${context ?? 'Unknown Context'}');
|
||||
debugPrint(' Message: ${getUserMessage(error)}');
|
||||
debugPrint(' Technical: ${getTechnicalDetails(error)}');
|
||||
DebugLogger.log(
|
||||
'🔴 ERROR [$timestamp] ${context ?? 'Unknown Context'}',
|
||||
scope: 'api/error-service',
|
||||
);
|
||||
DebugLogger.log(
|
||||
' Message: ${getUserMessage(error)}',
|
||||
scope: 'api/error-service',
|
||||
);
|
||||
DebugLogger.log(
|
||||
' Technical: ${getTechnicalDetails(error)}',
|
||||
scope: 'api/error-service',
|
||||
);
|
||||
|
||||
if (additionalData != null && additionalData.isNotEmpty) {
|
||||
debugPrint(' Additional Data: $additionalData');
|
||||
DebugLogger.log(
|
||||
' Additional Data: $additionalData',
|
||||
scope: 'api/error-service',
|
||||
);
|
||||
}
|
||||
|
||||
if (stackTrace != null) {
|
||||
debugPrint(' Stack Trace: $stackTrace');
|
||||
DebugLogger.log(
|
||||
' Stack Trace: $stackTrace',
|
||||
scope: 'api/error-service',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import 'api_error.dart';
|
||||
import '../utils/debug_logger.dart';
|
||||
|
||||
void debugPrint(String? message, {int? wrapWidth}) {
|
||||
if (message == null) return;
|
||||
DebugLogger.fromLegacy(message, scope: 'api/error-parser');
|
||||
}
|
||||
|
||||
/// Comprehensive error response parser
|
||||
/// Handles various API error response formats and extracts structured information
|
||||
class ErrorParser {
|
||||
@@ -29,7 +24,10 @@ class ErrorParser {
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('ErrorParser: Error parsing response: $e');
|
||||
DebugLogger.log(
|
||||
'ErrorParser: Error parsing response: $e',
|
||||
scope: 'api/error-parser',
|
||||
);
|
||||
return ParsedErrorResponse(
|
||||
message: 'Failed to parse error response',
|
||||
metadata: {
|
||||
|
||||
Reference in New Issue
Block a user