Error Handling Testing Checklist (2026)
A comprehensive Error Handling Testing Checklist (2026) is crucial for building robust and resilient software. This guide provides a detailed, actionable checklist for QA and development professionals
A comprehensive Error Handling Testing Checklist (2026) is crucial for building robust and resilient software. This guide provides a detailed, actionable checklist for QA and development professionals to systematically identify and address potential failure points in applications. Effective error handling is not merely about preventing crashes; it's about maintaining application stability, ensuring data integrity, providing informative user feedback, and ultimately, delivering a seamless user experience even when things go wrong. We will explore various facets of error handling, from explicit error conditions to subtle edge cases, covering functional, non-functional, and accessibility aspects, complete with pass criteria and practical examples.
The Pillars of Effective Error Handling
Before diving into the checklist, it's essential to understand the core principles that underpin robust error handling. These principles guide our testing efforts and help define what "good" error handling looks like.
User Experience First
The primary goal of error handling, from a user's perspective, is to minimize disruption and provide clear pathways to resolution. This means avoiding cryptic messages, unhandled exceptions, and dead-end states. Users should feel informed and in control, even when an error occurs.
Predictability and Consistency
Errors should be handled predictably across the application. Similar types of errors (e.g., network issues, validation failures) should ideally present with a consistent tone, style, and mechanism to the user. This reduces cognitive load and builds user trust.
Informative and Actionable Feedback
An error message like "An error occurred" is unhelpful. Good error messages explain *what* went wrong (in user-friendly terms), *why* it might have happened (if known), and *what* the user can do next (e.g., "Check your internet connection," "Try again later," "Contact support with this reference ID").
Graceful Degradation
When a component or service fails, the entire application shouldn't collapse. Error handling should aim for graceful degradation, allowing other parts of the application to continue functioning if possible. This is particularly important in microservices architectures.
Security and Data Integrity
Error messages should *never* expose sensitive system information (e.g., stack traces, database schemas, internal API keys). Furthermore, error conditions must not lead to data corruption or unauthorized access. Transactions should be rolled back or compensated to maintain data consistency.
Error Handling Testing Checklist (2026): Functional Scenarios
This section focuses on testing how the application behaves when encountering expected and unexpected functional errors.
Input Validation Errors
Input validation is the first line of defense against many issues, from data corruption to security vulnerabilities. Testing this thoroughly is paramount.
| Item No. | Test Case Description | Pass Criteria | Example |
|---|---|---|---|
| 1.1 | Empty/Missing Required Fields: Submit forms/requests with mandatory fields left blank. | Application prevents submission or displays clear error message for each missing field. Focus remains on the first invalid field. | Attempt to register with an empty username. Message: "Username cannot be empty." |
| 1.2 | Invalid Data Formats: Enter data that doesn't conform to expected types (e.g., text in a numeric field, invalid email format). | Application rejects input with specific, user-friendly error messages. No crashes or data corruption. | Enter "abc" in an age field. Message: "Age must be a number." |
| 1.3 | Out-of-Range Values: Submit values outside defined minimum/maximum limits (e.g., age < 0 or > 150, password too short/long). | Application rejects input with boundary-specific error messages. | Enter password "123" if min length is 8. Message: "Password must be at least 8 characters." |
| 1.4 | Special Characters/SQL Injection/XSS: Input malicious strings (e.g., ' OR 1=1; --, ) into text fields. | Application sanitizes or rejects input. No unexpected behavior, data breaches, or script execution. | Input ' OR 1=1; -- in a search bar. Expected: Treated as literal string, no database access. |
| 1.5 | Duplicate Values (Unique Constraints): Attempt to create resources with values that must be unique (e.g., existing username, email). | Application returns an error indicating the uniqueness violation. | Register with an email already in use. Message: "This email is already registered." |
| 1.6 | Rate Limiting/Flood Protection: Repeatedly submit forms or API requests within a short timeframe. | Application temporarily blocks or challenges the user (e.g., CAPTCHA), preventing abuse. | 5 failed login attempts in 1 minute leads to a 30-second lockout. |
Business Logic Errors
These errors occur when the application's internal rules or states prevent an action from completing successfully.
| Item No. | Test Case Description | Pass Criteria | Example |
|---|---|---|---|
| 2.1 | Insufficient Permissions: Attempt to perform an action without the necessary user roles or permissions. | Application displays an "Access Denied" or "Unauthorized" error message. Action is prevented. | A 'Guest' user attempts to delete an admin-only resource. Message: "You do not have permission to perform this action." |
| 2.2 | Unavailable Resources: Attempt to access or modify resources that no longer exist or are currently locked/unavailable. | Application gracefully handles the state, informing the user (e.g., "Item not found," "Resource currently in use"). | Try to purchase an item that just went out of stock. Message: "Sorry, this item is no longer available." |
| 2.3 | Invalid State Transitions: Attempt to perform an action that is not valid given the current state of an object (e.g., cancelling an already shipped order, approving an already approved request). | Application prevents the action and provides a state-specific error message. | Attempt to edit an invoice marked as 'Paid'. Message: "Cannot edit a paid invoice." |
| 2.4 | External Service Failures (Simulated): Simulate failures from integrated third-party services (e.g., payment gateway, shipping API, identity provider). | Application catches the error, provides a fallback, retries if appropriate, or informs the user about the external issue. | Payment gateway returns a "transaction declined" error. App shows: "Payment failed. Please try again or use another payment method." |
| 2.5 | Concurrency Conflicts: Simulate multiple users attempting to modify the same resource simultaneously. | Application handles conflicts (e.g., optimistic locking, last-write-wins) without data corruption, informing users if their changes weren't saved. | Two users edit the same document. One user's changes are applied, the other gets "Conflict detected. Please review and re-save." |
System-Level and Infrastructure Errors
These are often harder to reproduce but critical for application resilience.
| Item No. | Test Case Description | Pass Criteria | Example |
|---|---|---|---|
| 3.1 | Network Disconnections (Client-side): Simulate loss of internet connectivity during various operations (form submission, data fetching, navigation). | Application informs the user about the network issue. Pending operations are queued for retry or explicitly failed. No data loss. | User loses Wi-Fi during a file upload. Message: "Network connection lost. Upload paused." |
| 3.2 | Server-side Network Latency/Timeouts: Introduce artificial delays or timeouts in API responses. | Application handles delays gracefully (e.g., loading spinners) and times out cleanly, providing an appropriate message without crashing. | API call takes >30 seconds. App shows "Request timed out. Please try again." |
| 3.3 | Database Connection Failures/Unavailability: Simulate the database being offline or unreachable. | Application provides a generic "Service Unavailable" message to the user, logs the specific database error internally. | Database goes down. User sees: "Our services are temporarily unavailable. Please try again shortly." |
| 3.4 | Out of Memory/Resource Exhaustion: Stress test the application to consume excessive memory or CPU. | Application either gracefully shuts down, logs the issue, or provides an appropriate error message without crashing the entire system. | Heavy data processing causes OOM. System logs OOM error; user sees "An unexpected error occurred." |
| 3.5 | File System Errors: Test scenarios where the application cannot read from or write to the file system (e.g., permissions issues, full disk). | Application handles the error, informs the user or logs the specific issue, and prevents data loss. | Attempt to save a file to a full disk. Message: "Not enough space to save." |
Error Handling Testing Checklist (2026): Non-Functional Aspects
Error handling extends beyond just the functional correctness. How errors are presented and the system's behavior under duress are equally important.
User Interface and User Experience (UI/UX) for Errors
The presentation of errors significantly impacts user perception and satisfaction.
| Item No. | Test Case Description | Pass Criteria | Example |
|---|---|---|---|
| 4.1 | Clear and Understandable Error Messages: Evaluate all error messages for clarity, conciseness, and user-friendliness. | Messages avoid jargon, are grammatically correct, and provide context. | Instead of "Error 400: Bad Request," show "The information you provided is incomplete. Please check highlighted fields." |
| 4.2 | Actionable Error Messages: Ensure error messages guide the user on what to do next. | Messages suggest potential solutions or next steps. | Message: "Your session has expired. Please log in again." (with a "Log In" button). |
| 4.3 | Consistent Error Display: Verify that error messages appear consistently across the application (e.g., location, styling, tone). | Error messages use a defined visual style guide and appear in predictable UI elements (e.g., inline, at top of form, modal). | All validation errors appear in red text below the input field. |
| 4.4 | Transient vs. Persistent Errors: Test how errors that resolve themselves (e.g., temporary network glitch) are displayed versus those requiring user action. | Transient errors might use a temporary toast message; persistent errors require explicit user dismissal or action. | "Connecting..." toast for network, vs. persistent banner "Your account is suspended." |
| 4.5 | Error States in Complex Workflows: Test how errors are handled in multi-step processes or guided flows. | The application allows users to return to a previous step, restart the workflow, or clearly indicates which step failed. | During a multi-step checkout, a payment error allows user to go back to payment method selection. |
| 4.6 | Error States for Asynchronous Operations: Verify feedback for long-running processes (e.g., file uploads, data synchronization). | Users receive clear indicators of progress, success, or failure, with appropriate messages. | File successfully uploaded, or "Upload failed: file size too large." |
Accessibility (WCAG) for Error Handling
Ensuring error messages are accessible to all users is a critical aspect of inclusive design.
| Item No. | Test Case Description | Pass Criteria | Example |
|---|---|---|---|
| 5.1 | Error Identification: Verify that errors are not solely communicated by color. | Errors are indicated by text, icons, or patterns in addition to color. | A red border *and* an error icon next to an invalid field. |
| 5.2 | Error Description: Check that error messages are programmatically determinable and associated with the input field. | Screen readers can announce the error message along with the field it pertains to (e.g., using aria-describedby). | When tabbing to an invalid email field, screen reader announces "Email field, invalid format, please enter a valid email." |
| 5.3 | Error Prevention (WCAG 2.1, 3.3.4): For legal or financial data, ensure errors are preventable or reversible. | Users can review and correct input before final submission. | A confirmation step before completing a financial transaction. |
| 5.4 | Focus Management: When an error occurs, ensure focus is moved logically. | Focus shifts to the first error field or to the error summary message, allowing easy navigation. | On form submission with errors, focus moves to the first invalid input field. |
Security and Privacy in Error Handling
Error messages can inadvertently expose sensitive information, creating security risks.
| Item No. | Test Case Description | Pass Criteria | Example |
|---|---|---|---|
| 6.1 | Information Disclosure (Stack Traces, DB Errors): Intentionally trigger server-side errors (e.g., invalid API calls, malformed requests) to see if stack traces, internal server paths, or database error codes are exposed in the UI or API responses. | Generic error messages are displayed to users. Detailed errors are logged *server-side only*. | User sees "An unexpected error occurred" instead of java.lang.NullPointerException at com.app.Service.doSomething(). |
| 6.2 | Authentication/Authorization Errors: Verify that login/registration errors do not reveal whether a username/email exists. | Generic messages like "Invalid username or password" are used to prevent enumeration attacks. | Login attempt with non-existent user: "Invalid username or password." Login attempt with existing user, wrong password: "Invalid username or password." |
| 6.3 | Sensitive Data in Logs: Check server logs for inadvertently recorded sensitive user data (passwords, PII) during error conditions. | Logs contain sanitized information or masked data for sensitive fields. | Password fields are logged as **** instead of cleartext during a validation error. |
Performance and Reliability under Error Conditions
How the system performs when errors happen, especially at scale.
| Item No. | Test Case Description | Pass Criteria | Example |
|---|---|---|---|
| 7.1 | Performance Impact of Error Logging: Simulate a high volume of errors and monitor logging system performance and resource consumption. | Error logging does not significantly degrade application performance or exhaust system resources (e.g., disk space, CPU). | Under heavy load with errors, log file size and CPU usage remain within acceptable limits. |
| 7.2 | Impact of Retries/Backoff: Trigger transient errors (e.g., network glitches) and observe the application's retry mechanism. | Retries occur with appropriate exponential backoff, preventing thundering herd problems, and eventually inform the user on persistent failure. | Failed API call retries 3 times with increasing delays (1s, 3s, 9s) before reporting failure. |
| 7.3 | Circuit Breaker/Bulkhead Behavior: Simulate repeated failures of an external service or internal component to trigger circuit breaker patterns. | The circuit breaker opens, preventing further calls to the failing component, and gracefully degrades functionality or provides a fallback. | Repeated payment gateway failures cause the payment module to switch to a 'maintenance' mode, preventing new payment attempts. |
| 7.4 | Resource Leakage on Error: Introduce errors during resource acquisition (e.g., database connections, file handles) and check for leaks. | All acquired resources are properly released even when errors occur. | A database connection is closed after a query error, not left open indefinitely. |
Error Handling Testing Checklist (2026): Release Readiness
Before deploying, a final check on the operational aspects of error handling.
| Item No. | Test Case Description | Pass Criteria | Example |
|---|---|---|---|
| 8.1 | Monitoring and Alerting: Verify that critical errors trigger appropriate alerts (e.g., PagerDuty, Slack, email) for operations teams. | Alerts are sent for specific error types (e.g., 5xx server errors, critical application exceptions), contain sufficient context, and are routed to the correct teams. | A surge in 500 errors triggers a PagerDuty alert for the SRE team. |
| 8.2 | Logging and Traceability: Check that error logs contain sufficient information for debugging and post-mortem analysis (e.g., correlation IDs, timestamps, user IDs, request details). | Logs are structured, include necessary context, and can be correlated across services using tracing IDs. | An error log entry includes trace_id: abc123def456, user_id: 123, endpoint: /api/v1/orders, error_message: DB connection pool exhausted. |
| 8.3 | Error Reporting Tools Integration: Confirm integration with error reporting tools (e.g., Sentry, Bugsnag, New Relic) is functional. | Errors are correctly captured, grouped, and reported to the chosen tool with stack traces and relevant context. | A frontend JavaScript error is automatically reported to Sentry with browser details and user context. |
| 8.4 | Error Recovery Procedures: Confirm that documented procedures exist for common error scenarios (e.g., database recovery, service restart). | Operations teams have runbooks or playbooks for known error conditions. | Runbook for "Payment Gateway Downtime" outlines steps for failover or manual processing. |
Automated Approaches to Error Handling Testing
Manually executing this entire checklist for every release is impractical. Automation is key. Here's how various automation strategies can address different aspects of error handling.
Unit and Integration Tests
These are the foundational layers for catching errors early.
# Example: Unit test for input validation in a Python Flask app
import pytest
from app import create_app
@pytest.fixture
def client():
app = create_app()
app.config['TESTING'] = True
with app.test_client() as client:
yield client
def test_register_empty_username(client):
response = client.post('/register', json={'username': '', 'password': 'password123'})
assert response.status_code == 400
assert 'Username cannot be empty' in response.json['message']
def test_register_invalid_email_format(client):
response = client.post('/register', json={'username': 'testuser', 'email': 'invalid-email', 'password': 'password123'})
assert response.status_code == 400
assert 'Invalid email format' in response.json['message']
# Example: Integration test for a service returning an error
def test_order_creation_unavailable_product(mocker):
# Mock the inventory service to return an error
mocker.patch('app.inventory_service.check_stock', return_value={'success': False, 'message': 'Product out of stock'})
response = client.post('/order', json={'productId': 'unavailable-product', 'quantity': 1})
assert response.status_code == 400
assert 'Product out of stock' in response.json['message']
Coverage: Items 1.1-1.6 (Input Validation), 2.1-2.3 (Basic Business Logic), 2.4 (Simulated External Service Failures for specific known error codes).
API Testing (Postman/Newman, RestAssured, Cypress API)
API tests are excellent for validating server-side error responses without UI interaction.
# Example: Using curl to test an API endpoint with invalid data
curl -X POST -H "Content-Type: application/json" \
-d '{"email": "bademail", "password": "short"}' \
http://localhost:8080/api/v1/users/register
# Expected response (example):
# HTTP/1.1 400 Bad Request
# Content-Type: application/json
# {
# "code": "VALIDATION_ERROR",
# "message": "Validation failed",
# "details": [
# {"field": "email", "error": "Invalid email format"},
# {"field": "password", "error": "Password must be at least 8 characters"}
# ]
# }
Coverage: Items 1.1-1.6 (Input Validation), 2.1-2.3 (Business Logic), 2.4 (External Service Failures via mock servers or explicit error injection), 6.1-6.2 (Security: Information Disclosure, Auth errors).
UI/End-to-End (E2E) Testing (Selenium, Playwright, Cypress)
These tests validate the user's experience of errors directly, including UI presentation and state changes.
// Example: Playwright test for form validation error
test('should display error for empty required field', async ({ page }) => {
await page.goto('/register');
await page.click('button[type="submit"]'); // Submit empty form
// Expect error message to be visible
await expect(page.locator('text=Username cannot be empty')).toBeVisible();
// Expect focus to be on the username field
await expect(page.locator('#username-input')).toBeFocused();
});
// Example: Playwright test for network error during data fetch
test('should handle network disconnection during data load', async ({ page }) => {
await page.goto('/dashboard');
// Simulate network offline
await page.context().setOffline(true);
await page.reload(); // Reload while offline
// Expect a network error message or fallback UI
await expect(page.locator('text=Network connection lost. Please check your internet.')).toBeVisible();
// Simulate network online again
await page.context().setOffline(false);
await page.reload(); // Reload to recover
// Expect data to load successfully
await expect(page.locator('text=Welcome back!')).toBeVisible();
});
Coverage: Items 1.1-1.6 (Input Validation, UI display), 2.1-2.3 (Business Logic, UI feedback), 3.1 (Client-side Network Disconnections), 4.1-4.6 (UI/UX for Errors), 5.1-5.4 (Accessibility aspects visible in UI).
Chaos Engineering and Fault Injection
For system-level and infrastructure errors, chaos engineering tools (e.g., Chaos Monkey, LitmusChaos) or targeted fault injection are invaluable.
# Example: Using `tc` (traffic control) to simulate network latency
# Add 200ms delay to all outgoing traffic on eth0
sudo tc qdisc add dev eth0 root netem delay 200ms
# Remove the delay
sudo tc qdisc del dev eth0 root netem
# Example: Stopping a database service (highly disruptive, use with caution)
sudo systemctl stop postgresql
# Example: Using a dedicated fault injection tool (e.g., `toxiproxy` for network proxies)
# toxiproxy-cli create my_service -l localhost:8000 -u upstream.service:8080
# toxiproxy-cli toxic add my_service -t latency -a latency=2000 # Add 2s latency
# toxiproxy-cli toxic add my_service -t timeout -a timeout=5000 # Add 5s timeout
Coverage: Items 3.1-3.5 (System-Level Errors), 7.2-7.3 (Retries, Circuit Breakers). These are crucial for testing resilience.
Autonomous Testing Platforms
Platforms like SUSATest offer a powerful, holistic approach to error handling by automatically exploring applications and identifying issues without pre-written scripts.
How SUSATest Addresses the Checklist:
SUSATest works by "seeing" and interacting with the application like a human user. When an APK is uploaded or a web URL is provided, it intelligently navigates, taps buttons, types into fields, scrolls, and handles various UI elements. This exploratory nature inherently covers a significant portion of the error handling checklist:
- Input Validation (1.1-1.6): SUSATest, especially with personas like "adversarial" or "curious," will naturally attempt to input invalid data types, empty fields, special characters, and out-of-range values into input fields. It observes the application's response, detecting if an error message appears, if the app crashes (ANR), or if an unexpected state occurs. For example, if it tries to type text into a numeric-only field and the app crashes, that's a direct error detection.
- Business Logic Errors (2.1-2.3): As SUSATest navigates flows, it performs actions based on its understanding of the UI. If it attempts an action (e.g., clicking a disabled button, submitting an invalid state) and the application throws an unhandled exception or enters a deadlock, SUSATest flags it. Its ability to track flows (e.g., login, signup, checkout) means it can identify if a specific step fails due to a business rule violation and report a PASS/FAIL verdict for that flow.
- System-Level Errors (3.1-3.5): While SUSATest doesn't directly "pull the plug" on a database, it's highly effective at identifying the *symptoms* of underlying system errors. Crashes, ANRs (Application Not Responding), and dead buttons are often direct results of network issues, server errors, or resource exhaustion. If an API call fails due to a backend issue, SUSATest detects the resulting UI error state or crash.
- UI/UX for Errors (4.1-4.6): A key strength of SUSATest is its ability to observe the application's visual and interactive state. If an error occurs, it checks if an error message is displayed, if the UI becomes unresponsive, or if the application enters an unexpected loop. The platform can detect if a required element is missing or if the app is stuck.
- Accessibility (WCAG) (5.1-5.4): SUSATest includes WCAG violation detection. This means it can identify if error messages lack proper contrast, if focus management is incorrect for error states, or if critical information is conveyed solely by color.
- Security (6.1): While not a penetration testing tool, SUSATest will flag if a full stack trace is displayed to the user on an error, which is a common security vulnerability related to information disclosure.
- Performance (7.1-7.4): By monitoring ANRs and general responsiveness, SUSATest can indirectly detect performance degradation under error conditions.
Cross-Session Learning: SUSATest's cross-session learning is particularly powerful for error handling. If it previously encountered a dead end or a specific error condition on a certain screen, it remembers this. In subsequent runs, it can either avoid that path if it's truly a dead end or re-test the error condition to ensure it's resolved or handled differently. This iterative learning makes each test run smarter and more efficient at uncovering subtle error-related issues that might be missed by static scripts.
Auto-Generated Scripts: After finding errors, SUSATest doesn't just report them; it auto-generates regression scripts (Appium for Android, Playwright for Web) that pinpoint the exact steps to reproduce the issue. This is invaluable for developers to fix bugs and for QA to incorporate these specific error scenarios into their continuous integration pipeline.
# Example: A SUSATest CLI command to run an autonomous test
pip install susatest-agent
susatest run --app-type android --apk-path /path/to/my_app.apk --persona adversarial --flow login,checkout
This single command can initiate an exploration that touches upon dozens of error handling scenarios defined in our checklist, making it an indispensable tool for comprehensive error handling validation.
Real-World Edge Cases and How to Test Them
Many critical errors manifest in subtle, hard-to-reproduce edge cases. Here are a few examples and strategies for testing them.
The "Thundering Herd" Problem
Scenario: A backend service becomes temporarily unavailable. Multiple clients simultaneously detect the failure and all attempt to retry at the exact same moment. This creates a "thundering herd" of requests that overwhelms the recovering service, preventing it from ever getting back online.
Testing Strategy:
- Fault Injection: Use tools like Chaos Monkey or
toxiproxyto repeatedly make a critical backend service unavailable for short bursts. - Load Testing: During the fault injection, simulate high user load (e.g., 1000 concurrent users).
- Monitor Retries: Observe the client-side retry logic. Ensure it implements exponential backoff with jitter (randomized delays) to spread out retries.
- Monitor Service Recovery: After the fault is removed, verify that the backend service can recover and handle the subsequent traffic gracefully, without being overwhelmed by delayed retries.
Pass Criteria: The application's retry mechanism (client-side or API gateway) prevents a surge of requests from overwhelming the recovering service. The service eventually recovers and processes requests.
Data Inconsistency on Partial Failure
Scenario: A multi-step operation (e.g., creating an order that involves updating inventory, charging a card, and sending a notification) fails midway. For instance, the inventory is updated, but the payment fails.
Testing Strategy:
- Transactional Testing: Design tests that specifically target multi-step operations.
- Controlled Failure Points: Introduce failures at various points within the transaction (e.g., mock the payment gateway to fail *after* inventory update but *before* notification).
- **Database
Test Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free