asyncState.isError
Computed property indicating error state—has error and not currently loading.
Quick Start (30 seconds)
const state = asyncState(null);
console.log(state.isError); // false
await execute(state, async () => {
throw new Error('Something went wrong!');
});
console.log(state.isError); // true
console.log(state.error.message); // 'Something went wrong!'
// Use for error handling
if (state.isError) {
showErrorMessage(state.error.message);
}The magic: isError is true when operation failed—perfect for error UI!
What is asyncState.isError?
isError is a computed read-only property that returns true when the async state has an error and is not currently loading. It checks two conditions: error exists and not loading.
Key points:
- Read-only computed property
- True when:
error !== nullANDloading === false - False otherwise
- Updates automatically when dependencies change
- Reactive—can be watched
Why Does This Exist?
Without isError
const state = asyncState(null);
// Must check multiple conditions
if (state.error !== null && !state.loading) {
console.log('Error occurred');
}
// Easy to show error while still loading
if (state.error) { // Wrong! Might still be loading
console.log('Premature error display');
}Problem: Must check both error and loading, easy to get wrong.
With isError
const state = asyncState(null);
// Single, clear check
if (state.isError) {
console.log('Error occurred');
}Solution: One property that checks both conditions correctly.
Basic Usage
Example 1: Simple Error Check
const state = asyncState(null);
console.log(state.isError); // false
await execute(state, async () => {
throw new Error('Failed to load');
});
console.log(state.isError); // true
console.log(state.error); // Error: Failed to loadExample 2: Error Display
const state = asyncState(null);
function render() {
if (state.loading) {
return '<div>Loading...</div>';
}
if (state.isError) {
return `
<div class="error">
<h3>Error</h3>
<p>${state.error.message}</p>
<button onclick="retry()">Retry</button>
</div>
`;
}
if (state.isSuccess) {
return `<div>Data loaded</div>`;
}
return '<button>Load</button>';
}Example 3: Error Actions
const state = asyncState(null);
watch(state, {
isError: (hasError) => {
if (hasError) {
console.error('Error occurred:', state.error.message);
showNotification({
type: 'error',
message: state.error.message
});
logErrorToService(state.error);
}
}
});
await execute(state, async () => {
throw new Error('Network timeout');
});
// Shows notification automaticallyCommon Patterns
Pattern 1: Error Recovery
const state = asyncState(null);
async function loadWithRecovery() {
await execute(state, async () => {
const response = await fetch('/api/data');
return response.json();
});
if (state.isError) {
console.log('Primary source failed, trying backup...');
await execute(state, async () => {
const response = await fetch('/api/backup/data');
return response.json();
});
}
return state.isSuccess;
}Pattern 2: Error Type Handling
const state = asyncState(null);
await execute(state, async () => {
const response = await fetch('/api/data');
if (!response.ok) {
const error = new Error(`HTTP ${response.status}`);
error.status = response.status;
throw error;
}
return response.json();
});
if (state.isError) {
const error = state.error;
if (error.status === 404) {
console.log('Resource not found');
} else if (error.status >= 500) {
console.log('Server error, please try again');
} else {
console.log('Request error:', error.message);
}
}Pattern 3: Multiple State Errors
const usersState = asyncState(null);
const postsState = asyncState(null);
const hasAnyError = computed(() => {
return usersState.isError || postsState.isError;
});
const allErrors = computed(() => {
const errors = [];
if (usersState.isError) errors.push(usersState.error);
if (postsState.isError) errors.push(postsState.error);
return errors;
});
// Load both
execute(usersState, async () => {
return fetch('/api/users').then(r => r.json());
});
execute(postsState, async () => {
return fetch('/api/posts').then(r => r.json());
});
watch(hasAnyError, (hasError) => {
if (hasError) {
console.error('Errors occurred:', allErrors.value);
}
});Pattern 4: Error Boundary
const state = asyncState(null);
async function safeExecute(fn) {
await execute(state, fn);
if (state.isError) {
console.error('Operation failed:', state.error.message);
// Prevent error propagation
return {
success: false,
error: state.error.message
};
}
return {
success: true,
data: state.data
};
}
const result = await safeExecute(async () => {
const response = await fetch('/api/data');
return response.json();
});
console.log(result); // { success: false, error: '...' }Understanding the Conditions
Both Conditions Must Be True
const state = asyncState(null);
// Condition 1: error !== null
console.log(state.error !== null); // false
// Condition 2: loading === false
console.log(state.loading === false); // true
// Result: isError
console.log(state.isError); // false (no error)
await execute(state, async () => {
throw new Error('Failed');
});
console.log(state.error !== null); // true ✓
console.log(state.loading === false); // true ✓
console.log(state.isError); // true ✓Why Loading Check Matters
const state = asyncState(null);
// Start request that will fail
execute(state, async () => {
await new Promise(r => setTimeout(r, 1000));
throw new Error('Failed');
});
// Immediately check (while loading)
console.log(state.error); // null
console.log(state.loading); // true
console.log(state.isError); // false (still loading)
// After completion
await new Promise(r => setTimeout(r, 1500));
console.log(state.error); // Error: Failed
console.log(state.loading); // false
console.log(state.isError); // true (now errored)Key insight: isError waits for loading to finish before becoming true.
Edge Cases
Gotcha 1: Error Cleared on Retry
const state = asyncState(null);
await execute(state, async () => {
throw new Error('First error');
});
console.log(state.isError); // true
// Retry clears error immediately
execute(state, async () => {
console.log('Inside:', state.isError); // false (loading)
return 'success';
});
console.log('Outside:', state.isError); // false (loading)Gotcha 2: Error Persists with Old Data
const state = asyncState(null);
// First successful load
await execute(state, async () => 'old data');
console.log(state.isSuccess); // true
// Second load fails
await execute(state, async () => {
throw new Error('Failed');
});
console.log(state.data); // 'old data' (still there)
console.log(state.isError); // true
console.log(state.isSuccess); // false (error takes precedence)Gotcha 3: Aborted Operations Don't Set Error
const state = asyncState(null);
execute(state, async (signal) => {
await fetch('/api/data', { signal });
return 'data';
});
setTimeout(() => abort(state), 100);
await new Promise(r => setTimeout(r, 200));
console.log(state.error); // null (abort not an error)
console.log(state.isError); // falseKey insight: Aborted operations don't count as errors.
isError vs Manual Checks
❌ Manual (Verbose)
// Must check both conditions
if (state.error && state.error !== null && !state.loading) {
console.log('Error occurred');
}
// Easy to forget loading check
if (state.error) { // Wrong! Might still be loading
console.log('Premature error display');
}✅ With isError (Clean)
if (state.isError) {
console.log('Error occurred');
}When to Use
Use isError for:
- ✅ Error UI display
- ✅ Error notifications
- ✅ Retry logic
- ✅ Error logging
- ✅ Fallback handling
Don't use for:
- ❌ Checking if has error while loading (use
error !== null) - ❌ Checking success state (use
isSuccess) - ❌ Checking idle state (use
isIdle)
Summary
What it is: Computed property indicating error state
Formula: error !== null AND loading === false
Returns: Boolean
Read-only: Yes (computed, cannot be set)
Reactive: Yes—updates when dependencies change
Use for: Error-state conditional logic
Quick Reference
// Create async state
const state = asyncState(null);
// Check error
console.log(state.isError); // false
// After failed execute
await execute(state, async () => {
throw new Error('Failed!');
});
console.log(state.isError); // true
// Conditional logic
if (state.isError) {
console.error('Error:', state.error.message);
}
// Watch error changes
watch(state, {
isError: (hasError) => {
if (hasError) {
showErrorNotification(state.error);
}
}
});One-Line Rule: isError is true when operation failed (has error and not loading)—perfect for error-state UI.