sojorn/sojorn_app/lib/utils/error_handler.dart

88 lines
2.6 KiB
Dart

import 'dart:io';
import 'dart:async';
import 'package:flutter/material.dart';
/// Global error handler for consistent error messaging and logging
class ErrorHandler {
/// Handle an error and optionally show a snackbar to the user
static void handleError(
dynamic error, {
required BuildContext context,
String? userMessage,
bool showSnackbar = true,
}) {
final displayMessage = _getDisplayMessage(error, userMessage);
// Log to console (in production, send to analytics/crash reporting)
_logError(error, displayMessage);
if (showSnackbar && context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(displayMessage),
action: SnackBarAction(
label: 'Dismiss',
onPressed: () {},
),
duration: const Duration(seconds: 4),
backgroundColor: Colors.red[700],
),
);
}
}
/// Get user-friendly error message
static String _getDisplayMessage(dynamic error, String? userMessage) {
if (userMessage != null) return userMessage;
if (error is SocketException) {
return 'No internet connection. Please check your network.';
} else if (error is TimeoutException) {
return 'Request timed out. Please try again.';
} else if (error is FormatException) {
return 'Invalid data format received.';
} else if (error.toString().contains('401')) {
return 'Authentication error. Please sign in again.';
} else if (error.toString().contains('403')) {
return 'You don\'t have permission to do that.';
} else if (error.toString().contains('404')) {
return 'Resource not found.';
} else if (error.toString().contains('500')) {
return 'Server error. Please try again later.';
} else {
return 'Something went wrong. Please try again.';
}
}
/// Log error for debugging/analytics
static void _logError(dynamic error, String message) {
// In production, send to Sentry, Firebase Crashlytics, etc.
debugPrint('ERROR: $message');
debugPrint('Details: ${error.toString()}');
if (error is Error) {
debugPrint('Stack trace: ${error.stackTrace}');
}
}
}
/// Wrapper for async operations with automatic error handling
Future<T?> safeExecute<T>({
required Future<T> Function() operation,
required BuildContext context,
String? errorMessage,
bool showError = true,
}) async {
try {
return await operation();
} catch (e) {
if (showError) {
ErrorHandler.handleError(
e,
context: context,
userMessage: errorMessage,
);
}
return null;
}
}