Design System

Error Handling Patterns

Transform generic errors into specific, actionable messages that help users recover.

UX Issue in drmg-sales

"Got 'Failed to create deal' error with no specific error message explaining why"

Fix: Parse server errors and show field-specific validation messages.

Bad vs Good Error Messages

Failed to create dealBad

Deal amount is required

The "Expected Value" field must be filled in before saving.

Good: Specific + Actionable
Something went wrongBad

Unable to reach server

The request timed out after 30 seconds. This might be due to network issues.

Good: Specific + Actionable
Operation not allowedBad

You don't have permission to delete this contact

Only account admins can delete contacts with active deals.

Good: Specific + Actionable
Save failedBad

This contact was modified by someone else

Marcus Johnson updated this contact 2 minutes ago. Your changes conflict with theirs.

Good: Specific + Actionable
ErrorBad

Our servers are temporarily unavailable

We're experiencing high traffic. Your data has been saved locally.

Good: Specific + Actionable

Inline Field Validation

Show errors on individual fields as users interact, not just on submit.

$

Good Error Messages

  • Say what went wrong specifically
  • Explain why it happened (if known)
  • Tell the user how to fix it
  • Provide an action button when possible
  • Include technical details expandably

Bad Error Messages

  • "Something went wrong"
  • "Error"
  • "Failed to save"
  • "Invalid input"
  • "Operation not permitted"

Server Action Error Handling

// In your server action:
export async function createDeal(formData: FormData) {
  try {
    const result = await dealService.create(data);
    return { success: true, data: result };
  } catch (error) {
    // Map specific errors to user-friendly messages
    if (error.code === 'VALIDATION_ERROR') {
      return {
        success: false,
        error: {
          field: error.field,
          message: `${error.field} is required`,
          recoveryHint: 'Please fill in all required fields',
        },
      };
    }
    if (error.code === 'PERMISSION_DENIED') {
      return {
        success: false,
        error: {
          message: 'You don\'t have permission to create deals',
          recoveryHint: 'Contact your administrator for access',
        },
      };
    }
    // Log unknown errors but show user-friendly message
    console.error('Unexpected error:', error);
    return {
      success: false,
      error: {
        message: 'Unable to create deal right now',
        recoveryHint: 'Please try again or contact support',
        referenceId: generateErrorId(), // For support tickets
      },
    };
  }
}