Error Handling
The SDK throws four error types. Always check for AbortError first (request cancellation), then NetworkError, then MaintenanceError, then the base WorkAppsSDKError.
Error Types
DOMException (AbortError)
Thrown when a request is cancelled via AbortSignal or sdk.destroy(). This is not a network or server error — it means the request was intentionally cancelled.
1if (error instanceof DOMException && error.name === 'AbortError') {2 return; // cancelled — no action needed3}
NetworkError
Thrown when the fetch() call itself fails — device offline, DNS failure, etc. This means no response was received from the server. GET requests are retried automatically before this fires.
1if (error instanceof WorkAppsSDK.NetworkError) {2 showMessage('Check your internet connection.');3}
MaintenanceError
Thrown proactively when write operations are attempted while the SDK is in maintenance state (i.e. a previous request returned 503).
1if (error instanceof WorkAppsSDK.MaintenanceError) {2 showMessage('App is being updated. Try again shortly.');3}
WorkAppsSDKError
The base class for all server-side errors. Check error.code against ErrorCode constants.
1if (error instanceof WorkAppsSDK.WorkAppsSDKError) {2 const { ErrorCode } = WorkAppsSDK;34 if (error.code === ErrorCode.ValidationFailed) {5 // Show field-level errors6 const fieldErrors = error.getFieldErrors();7 // { fieldKey: 'first error message', ... }8 showFieldErrors(fieldErrors);910 } else if (error.code === ErrorCode.NotFound) {11 showMessage('Record not found.');1213 } else if (error.code === ErrorCode.AccessDenied) {14 showMessage('You do not have permission.');1516 } else if (error.code === ErrorCode.RateLimited) {17 // 429s are retried automatically — this only fires after all retries exhausted18 showMessage('Too many requests. Try again shortly.');1920 } else {21 // error.message is always human-readable22 console.error('[WorkApps]', error.toString());23 showMessage('Something went wrong. Please try again.');24 }25}
Complete Pattern
1const { ErrorCode, NetworkError, MaintenanceError, WorkAppsSDKError } = WorkAppsSDK;23try {4 await sdk.createRecord('tasks', data);5} catch (error) {6 if (error instanceof DOMException && error.name === 'AbortError') {7 return; // cancelled8 }9 if (error instanceof NetworkError) {10 showMessage('Check your internet connection.');11 } else if (error instanceof MaintenanceError) {12 showMessage('App is being updated. Try again shortly.');13 } else if (error instanceof WorkAppsSDKError) {14 if (error.code === ErrorCode.ValidationFailed) {15 showFieldErrors(error.getFieldErrors());16 } else {17 showMessage(error.message);18 }19 }20}
ErrorCode Constants
Use ErrorCode constants instead of hardcoded strings to avoid typos:
1const { ErrorCode } = WorkAppsSDK;2// or: import { ErrorCode } from 'https://sdk.workapps.tech/v1.js';
| Constant | Value | When thrown |
|---|---|---|
ErrorCode.Unauthorized |
UNAUTHORIZED |
Session expired |
ErrorCode.AccessDenied |
ACCESS_DENIED |
No permission for this app or record |
ErrorCode.MissingAppId |
MISSING_APP_ID |
Constructor called without appId and window.__WORKAPPS__ not set |
ErrorCode.NotFound |
NOT_FOUND |
Record, entity, or app not found |
ErrorCode.ReadOnlyRecord |
READ_ONLY_RECORD |
Record is read-only (e.g. the app's access mode is read_only) |
ErrorCode.ValidationFailed |
VALIDATION_FAILED |
Field validation error — check getFieldErrors() |
ErrorCode.StorageLimitReached |
STORAGE_LIMIT_REACHED |
Storage quota exceeded |
ErrorCode.RateLimited |
RATE_LIMITED |
Too many requests — retried automatically; throws if all retries exhausted |
ErrorCode.QueryTooComplex |
QUERY_TOO_COMPLEX |
Filter is too deeply nested or complex — simplify the filter |
ErrorCode.Maintenance |
MAINTENANCE |
App is in maintenance mode |
ErrorCode.NetworkError |
NETWORK_ERROR |
Network unreachable |
ErrorCode.Unknown |
UNKNOWN |
Unexpected server error |
Validation Field Errors
When error.code === ErrorCode.ValidationFailed, call error.getFieldErrors() to get a { fieldKey: 'message' } map of the first error per field:
1const fieldErrors = error.getFieldErrors();2// { title: 'This field is required.', status: 'Invalid value.' }34// Display inline below each field:5Object.entries(fieldErrors).forEach(([field, message]) => {6 const el = document.getElementById(`error-${field}`);7 if (el) el.textContent = message;8});
401 Handling
On 401, the SDK calls onUnauthorized() (defaults to redirecting to /login) then throws WorkAppsSDKError with ErrorCode.Unauthorized. Override onUnauthorized in the constructor to save draft state before redirecting.