feat: enhance error boundary widget with improved error handling and UI updates

- Added a method to ignore specific errors related to RenderFlex overflow.
- Refactored the error display layout to use a centered scrollable view.
- Improved visual presentation with a gradient background for the error icon and updated button styles for retry functionality.
This commit is contained in:
cogwheel0
2025-10-26 23:15:44 +05:30
parent c37151bba5
commit dded22f1ec
2 changed files with 102 additions and 34 deletions

View File

@@ -31,7 +31,19 @@ class _ErrorBoundaryState extends ConsumerState<ErrorBoundary> {
bool _hasError = false; bool _hasError = false;
void Function(FlutterErrorDetails details)? _previousOnError; void Function(FlutterErrorDetails details)? _previousOnError;
bool _shouldIgnoreError(Object error) {
// Ignore RenderFlex overflow errors (layout issues)
final errorString = error.toString();
return errorString.contains('RenderFlex') ||
errorString.contains('overflow') && errorString.contains('pixels');
}
void _scheduleHandleError(Object error, StackTrace? stack) { void _scheduleHandleError(Object error, StackTrace? stack) {
// Skip errors that should be ignored
if (_shouldIgnoreError(error)) {
return;
}
// Defer to next frame to avoid setState during build exceptions // Defer to next frame to avoid setState during build exceptions
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) { if (mounted) {
@@ -119,43 +131,99 @@ class _ErrorBoundaryState extends ConsumerState<ErrorBoundary> {
child: Scaffold( child: Scaffold(
backgroundColor: context.conduitTheme.surfaceBackground, backgroundColor: context.conduitTheme.surfaceBackground,
body: SafeArea( body: SafeArea(
child: Padding( child: Center(
padding: const EdgeInsets.all(16.0), child: SingleChildScrollView(
child: Column( padding: const EdgeInsets.symmetric(
mainAxisAlignment: MainAxisAlignment.center, horizontal: Spacing.pagePadding,
children: [ vertical: Spacing.lg,
Icon( ),
Icons.error_outline, child: Container(
size: 64, constraints: const BoxConstraints(maxWidth: 480),
color: context.conduitTheme.error, decoration: BoxDecoration(
), color: context.conduitTheme.cardBackground,
const SizedBox(height: 16), borderRadius: BorderRadius.circular(
Text( context.conduitTheme.radiusLg,
AppLocalizations.of(context)?.errorMessage ??
'An unexpected error occurred',
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
color: context.conduitTheme.textPrimary,
), ),
), border: Border.all(
const SizedBox(height: 8), color: context.conduitTheme.cardBorder,
Text( width: BorderWidth.regular,
enhancedErrorService.getUserMessage(_error!),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: context.conduitTheme.textSecondary,
), ),
boxShadow: context.conduitTheme.cardShadows,
), ),
if (widget.allowRetry) ...[ padding: const EdgeInsets.all(Spacing.xl),
const SizedBox(height: 24), child: Column(
FilledButton.icon( mainAxisSize: MainAxisSize.min,
onPressed: _retry, children: [
icon: const Icon(Icons.refresh), // Error icon with gradient background
label: Text( Container(
AppLocalizations.of(context)?.retry ?? 'Retry', width: 80,
height: 80,
decoration: BoxDecoration(
color: context.conduitTheme.errorBackground,
shape: BoxShape.circle,
),
child: Icon(
Icons.error_outline_rounded,
size: 40,
color: context.conduitTheme.error,
),
), ),
), const SizedBox(height: Spacing.lg),
],
], // Error title
Text(
AppLocalizations.of(context)?.errorMessage ??
'Something went wrong',
style: context.conduitTheme.headingSmall,
textAlign: TextAlign.center,
),
const SizedBox(height: Spacing.sm),
// Error description
Text(
enhancedErrorService.getUserMessage(_error!),
textAlign: TextAlign.center,
style: context.conduitTheme.bodySmall?.copyWith(
color: context.conduitTheme.textSecondary,
),
),
if (widget.allowRetry) ...[
const SizedBox(height: Spacing.xl),
// Retry button
SizedBox(
width: double.infinity,
child: FilledButton.icon(
onPressed: _retry,
icon: const Icon(Icons.refresh_rounded),
style: FilledButton.styleFrom(
backgroundColor: context.conduitTheme.buttonPrimary,
foregroundColor: context.conduitTheme.buttonPrimaryText,
padding: const EdgeInsets.symmetric(
horizontal: Spacing.lg,
vertical: Spacing.md,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
context.conduitTheme.radiusMd,
),
),
elevation: 0,
),
label: Text(
AppLocalizations.of(context)?.retry ?? 'Try Again',
style: context.conduitTheme.bodySmall?.copyWith(
fontWeight: FontWeight.w600,
color: context.conduitTheme.buttonPrimaryText,
),
),
),
),
],
],
),
),
), ),
), ),
), ),

Submodule openwebui-src updated: 43a2881074...7a83e7dfa3