/** * Typed error codes and status mapping for the EmDash REST API. * * All handler-level and route-level error codes are defined here. * Routes and handlers should import error codes from this module * instead of using ad-hoc strings. */ export const ErrorCode = { // Shared (used across domains) NOT_FOUND: "NOT_FOUND", VALIDATION_ERROR: "VALIDATION_ERROR", INVALID_INPUT: "INVALID_INPUT", INVALID_JSON: "INVALID_JSON", INVALID_CURSOR: "INVALID_CURSOR", CONFLICT: "CONFLICT", SLUG_CONFLICT: "SLUG_CONFLICT", NOT_CONFIGURED: "NOT_CONFIGURED", UNAUTHORIZED: "UNAUTHORIZED", FORBIDDEN: "FORBIDDEN", RATE_LIMITED: "RATE_LIMITED", NOT_AUTHENTICATED: "NOT_AUTHENTICATED", NOT_IMPLEMENTED: "NOT_IMPLEMENTED", NOT_SUPPORTED: "NOT_SUPPORTED", MISSING_PARAM: "MISSING_PARAM", CSRF_REJECTED: "CSRF_REJECTED", // Content CONTENT_CREATE_ERROR: "CONTENT_CREATE_ERROR", CONTENT_UPDATE_ERROR: "CONTENT_UPDATE_ERROR", CONTENT_DELETE_ERROR: "CONTENT_DELETE_ERROR", CONTENT_LIST_ERROR: "CONTENT_LIST_ERROR", CONTENT_GET_ERROR: "CONTENT_GET_ERROR", CONTENT_DUPLICATE_ERROR: "CONTENT_DUPLICATE_ERROR", CONTENT_RESTORE_ERROR: "CONTENT_RESTORE_ERROR", CONTENT_PUBLISH_ERROR: "CONTENT_PUBLISH_ERROR", CONTENT_UNPUBLISH_ERROR: "CONTENT_UNPUBLISH_ERROR", CONTENT_SCHEDULE_ERROR: "CONTENT_SCHEDULE_ERROR", CONTENT_UNSCHEDULE_ERROR: "CONTENT_UNSCHEDULE_ERROR", CONTENT_DISCARD_DRAFT_ERROR: "CONTENT_DISCARD_DRAFT_ERROR", CONTENT_COMPARE_ERROR: "CONTENT_COMPARE_ERROR", CONTENT_TRANSLATIONS_ERROR: "CONTENT_TRANSLATIONS_ERROR", CONTENT_COUNT_ERROR: "CONTENT_COUNT_ERROR", // Revisions REVISION_LIST_ERROR: "REVISION_LIST_ERROR", REVISION_GET_ERROR: "REVISION_GET_ERROR", REVISION_RESTORE_ERROR: "REVISION_RESTORE_ERROR", INVALID_REVISION: "INVALID_REVISION", // Schema SCHEMA_LIST_ERROR: "SCHEMA_LIST_ERROR", SCHEMA_GET_ERROR: "SCHEMA_GET_ERROR", SCHEMA_CREATE_ERROR: "SCHEMA_CREATE_ERROR", SCHEMA_UPDATE_ERROR: "SCHEMA_UPDATE_ERROR", SCHEMA_DELETE_ERROR: "SCHEMA_DELETE_ERROR", SCHEMA_EXPORT_ERROR: "SCHEMA_EXPORT_ERROR", SCHEMA_FIELD_LIST_ERROR: "SCHEMA_FIELD_LIST_ERROR", SCHEMA_FIELD_GET_ERROR: "SCHEMA_FIELD_GET_ERROR", SCHEMA_FIELD_CREATE_ERROR: "SCHEMA_FIELD_CREATE_ERROR", SCHEMA_FIELD_UPDATE_ERROR: "SCHEMA_FIELD_UPDATE_ERROR", SCHEMA_FIELD_DELETE_ERROR: "SCHEMA_FIELD_DELETE_ERROR", SCHEMA_FIELD_REORDER_ERROR: "SCHEMA_FIELD_REORDER_ERROR", // Byline schema (Discussion #1174). Reuses RESERVED_SLUG, INVALID_SLUG, // INVALID_TYPE, FIELD_EXISTS, NOT_FOUND, VALIDATION_ERROR where the // semantics match; the two below are byline-domain specific: TRANSLATABLE_LOCKED: "TRANSLATABLE_LOCKED", REORDER_MISMATCH: "REORDER_MISMATCH", ORPHAN_LIST_ERROR: "ORPHAN_LIST_ERROR", ORPHAN_REGISTER_ERROR: "ORPHAN_REGISTER_ERROR", COLLECTION_EXISTS: "COLLECTION_EXISTS", COLLECTION_NOT_FOUND: "COLLECTION_NOT_FOUND", TABLE_NOT_FOUND: "TABLE_NOT_FOUND", FIELD_EXISTS: "FIELD_EXISTS", FIELD_TYPE_COLUMN_CHANGE: "FIELD_TYPE_COLUMN_CHANGE", RESERVED_SLUG: "RESERVED_SLUG", INVALID_SLUG: "INVALID_SLUG", CREATE_FAILED: "CREATE_FAILED", UPDATE_FAILED: "UPDATE_FAILED", REGISTER_FAILED: "REGISTER_FAILED", // Media MEDIA_LIST_ERROR: "MEDIA_LIST_ERROR", MEDIA_GET_ERROR: "MEDIA_GET_ERROR", MEDIA_CREATE_ERROR: "MEDIA_CREATE_ERROR", MEDIA_UPDATE_ERROR: "MEDIA_UPDATE_ERROR", MEDIA_DELETE_ERROR: "MEDIA_DELETE_ERROR", NO_STORAGE: "NO_STORAGE", NO_FILE: "NO_FILE", INVALID_TYPE: "INVALID_TYPE", UPLOAD_ERROR: "UPLOAD_ERROR", UPLOAD_URL_ERROR: "UPLOAD_URL_ERROR", CONFIRM_ERROR: "CONFIRM_ERROR", CONFIRM_FAILED: "CONFIRM_FAILED", FILE_NOT_FOUND: "FILE_NOT_FOUND", INVALID_STATE: "INVALID_STATE", FILE_SERVE_ERROR: "FILE_SERVE_ERROR", STORAGE_NOT_CONFIGURED: "STORAGE_NOT_CONFIGURED", PROVIDER_LIST_ERROR: "PROVIDER_LIST_ERROR", PROVIDER_UPLOAD_ERROR: "PROVIDER_UPLOAD_ERROR", PROVIDER_GET_ERROR: "PROVIDER_GET_ERROR", PROVIDER_DELETE_ERROR: "PROVIDER_DELETE_ERROR", // Comments COMMENT_LIST_ERROR: "COMMENT_LIST_ERROR", COMMENT_GET_ERROR: "COMMENT_GET_ERROR", COMMENT_STATUS_ERROR: "COMMENT_STATUS_ERROR", COMMENT_DELETE_ERROR: "COMMENT_DELETE_ERROR", COMMENT_BULK_ERROR: "COMMENT_BULK_ERROR", COMMENT_INBOX_ERROR: "COMMENT_INBOX_ERROR", COMMENT_COUNTS_ERROR: "COMMENT_COUNTS_ERROR", COMMENT_CREATE_ERROR: "COMMENT_CREATE_ERROR", COMMENTS_DISABLED: "COMMENTS_DISABLED", COMMENTS_CLOSED: "COMMENTS_CLOSED", COMMENT_REJECTED: "COMMENT_REJECTED", // Auth ACCOUNT_DISABLED: "ACCOUNT_DISABLED", ADMIN_EXISTS: "ADMIN_EXISTS", SETUP_COMPLETE: "SETUP_COMPLETE", CREDENTIAL_EXISTS: "CREDENTIAL_EXISTS", CHALLENGE_EXPIRED: "CHALLENGE_EXPIRED", PASSKEY_REGISTER_ERROR: "PASSKEY_REGISTER_ERROR", PASSKEY_REGISTER_OPTIONS_ERROR: "PASSKEY_REGISTER_OPTIONS_ERROR", PASSKEY_OPTIONS_ERROR: "PASSKEY_OPTIONS_ERROR", PASSKEY_VERIFY_ERROR: "PASSKEY_VERIFY_ERROR", PASSKEY_LIST_ERROR: "PASSKEY_LIST_ERROR", PASSKEY_RENAME_ERROR: "PASSKEY_RENAME_ERROR", PASSKEY_DELETE_ERROR: "PASSKEY_DELETE_ERROR", PASSKEY_LIMIT: "PASSKEY_LIMIT", LAST_PASSKEY: "LAST_PASSKEY", LOGOUT_ERROR: "LOGOUT_ERROR", SELF_ROLE_CHANGE: "SELF_ROLE_CHANGE", EMAIL_IN_USE: "EMAIL_IN_USE", EMAIL_NOT_CONFIGURED: "EMAIL_NOT_CONFIGURED", USER_EXISTS: "USER_EXISTS", INVALID_TOKEN: "INVALID_TOKEN", TOKEN_EXPIRED: "TOKEN_EXPIRED", DOMAIN_NOT_ALLOWED: "DOMAIN_NOT_ALLOWED", INVITE_CREATE_ERROR: "INVITE_CREATE_ERROR", INVITE_VALIDATE_ERROR: "INVITE_VALIDATE_ERROR", INVITE_COMPLETE_ERROR: "INVITE_COMPLETE_ERROR", SIGNUP_VERIFY_ERROR: "SIGNUP_VERIFY_ERROR", SIGNUP_COMPLETE_ERROR: "SIGNUP_COMPLETE_ERROR", RECOVERY_SEND_ERROR: "RECOVERY_SEND_ERROR", USER_LIST_ERROR: "USER_LIST_ERROR", USER_DETAIL_ERROR: "USER_DETAIL_ERROR", USER_UPDATE_ERROR: "USER_UPDATE_ERROR", USER_DISABLE_ERROR: "USER_DISABLE_ERROR", USER_ENABLE_ERROR: "USER_ENABLE_ERROR", // OAuth (internal codes -- distinct from RFC OAuthErrorCode) UNSUPPORTED_RESPONSE_TYPE: "UNSUPPORTED_RESPONSE_TYPE", INVALID_REDIRECT_URI: "INVALID_REDIRECT_URI", INVALID_CLIENT: "INVALID_CLIENT", INVALID_SCOPE: "INVALID_SCOPE", AUTHORIZATION_ERROR: "AUTHORIZATION_ERROR", INVALID_GRANT: "INVALID_GRANT", UNSUPPORTED_GRANT_TYPE: "UNSUPPORTED_GRANT_TYPE", INVALID_CODE: "INVALID_CODE", EXPIRED_CODE: "EXPIRED_CODE", INSUFFICIENT_ROLE: "INSUFFICIENT_ROLE", INSUFFICIENT_SCOPE: "INSUFFICIENT_SCOPE", INSUFFICIENT_PERMISSIONS: "INSUFFICIENT_PERMISSIONS", TOKEN_EXCHANGE_ERROR: "TOKEN_EXCHANGE_ERROR", TOKEN_REFRESH_ERROR: "TOKEN_REFRESH_ERROR", TOKEN_REVOKE_ERROR: "TOKEN_REVOKE_ERROR", TOKEN_CREATE_ERROR: "TOKEN_CREATE_ERROR", TOKEN_LIST_ERROR: "TOKEN_LIST_ERROR", TOKEN_ERROR: "TOKEN_ERROR", DEVICE_CODE_ERROR: "DEVICE_CODE_ERROR", AUTHORIZE_ERROR: "AUTHORIZE_ERROR", CLIENT_LIST_ERROR: "CLIENT_LIST_ERROR", CLIENT_GET_ERROR: "CLIENT_GET_ERROR", CLIENT_CREATE_ERROR: "CLIENT_CREATE_ERROR", CLIENT_UPDATE_ERROR: "CLIENT_UPDATE_ERROR", CLIENT_DELETE_ERROR: "CLIENT_DELETE_ERROR", // Allowed domains DOMAIN_LIST_ERROR: "DOMAIN_LIST_ERROR", DOMAIN_CREATE_ERROR: "DOMAIN_CREATE_ERROR", DOMAIN_UPDATE_ERROR: "DOMAIN_UPDATE_ERROR", DOMAIN_DELETE_ERROR: "DOMAIN_DELETE_ERROR", // Plugins / Marketplace PLUGIN_LIST_ERROR: "PLUGIN_LIST_ERROR", PLUGIN_GET_ERROR: "PLUGIN_GET_ERROR", PLUGIN_ENABLE_ERROR: "PLUGIN_ENABLE_ERROR", PLUGIN_DISABLE_ERROR: "PLUGIN_DISABLE_ERROR", PLUGIN_ID_CONFLICT: "PLUGIN_ID_CONFLICT", MARKETPLACE_NOT_CONFIGURED: "MARKETPLACE_NOT_CONFIGURED", MARKETPLACE_UNAVAILABLE: "MARKETPLACE_UNAVAILABLE", MARKETPLACE_ERROR: "MARKETPLACE_ERROR", SANDBOX_NOT_AVAILABLE: "SANDBOX_NOT_AVAILABLE", ALREADY_INSTALLED: "ALREADY_INSTALLED", ALREADY_UP_TO_DATE: "ALREADY_UP_TO_DATE", NO_VERSION: "NO_VERSION", MANIFEST_MISMATCH: "MANIFEST_MISMATCH", MANIFEST_VERSION_MISMATCH: "MANIFEST_VERSION_MISMATCH", AUDIT_FAILED: "AUDIT_FAILED", CHECKSUM_MISMATCH: "CHECKSUM_MISMATCH", INVALID_BUNDLE: "INVALID_BUNDLE", BUNDLE_EXTRACT_FAILED: "BUNDLE_EXTRACT_FAILED", BUNDLE_DOWNLOAD_FAILED: "BUNDLE_DOWNLOAD_FAILED", AGGREGATOR_RESPONSE_INVALID: "AGGREGATOR_RESPONSE_INVALID", AGGREGATOR_HTTP_ERROR: "AGGREGATOR_HTTP_ERROR", AGGREGATOR_NOT_FOUND: "AGGREGATOR_NOT_FOUND", CAPABILITY_ESCALATION: "CAPABILITY_ESCALATION", ROUTE_VISIBILITY_ESCALATION: "ROUTE_VISIBILITY_ESCALATION", ENV_INCOMPATIBLE: "ENV_INCOMPATIBLE", INSTALL_FAILED: "INSTALL_FAILED", UNINSTALL_FAILED: "UNINSTALL_FAILED", SEARCH_FAILED: "SEARCH_FAILED", GET_PLUGIN_FAILED: "GET_PLUGIN_FAILED", GET_THEME_FAILED: "GET_THEME_FAILED", THEME_SEARCH_FAILED: "THEME_SEARCH_FAILED", UPDATE_CHECK_FAILED: "UPDATE_CHECK_FAILED", EXCLUSIVE_HOOKS_LIST_ERROR: "EXCLUSIVE_HOOKS_LIST_ERROR", EXCLUSIVE_HOOK_SET_ERROR: "EXCLUSIVE_HOOK_SET_ERROR", // Menus MENU_LIST_ERROR: "MENU_LIST_ERROR", MENU_CREATE_ERROR: "MENU_CREATE_ERROR", MENU_GET_ERROR: "MENU_GET_ERROR", MENU_UPDATE_ERROR: "MENU_UPDATE_ERROR", MENU_DELETE_ERROR: "MENU_DELETE_ERROR", MENU_ITEM_CREATE_ERROR: "MENU_ITEM_CREATE_ERROR", MENU_ITEM_UPDATE_ERROR: "MENU_ITEM_UPDATE_ERROR", MENU_ITEM_DELETE_ERROR: "MENU_ITEM_DELETE_ERROR", MENU_REORDER_ERROR: "MENU_REORDER_ERROR", // Returned when a menu name resolves to multiple locale variants and // the caller did not pass `locale` to disambiguate. (name, locale) is // unique, so this only fires for omitted-locale lookups. AMBIGUOUS_LOCALE: "AMBIGUOUS_LOCALE", // Taxonomies TAXONOMY_LIST_ERROR: "TAXONOMY_LIST_ERROR", TAXONOMY_CREATE_ERROR: "TAXONOMY_CREATE_ERROR", TERM_LIST_ERROR: "TERM_LIST_ERROR", TERM_CREATE_ERROR: "TERM_CREATE_ERROR", TERM_GET_ERROR: "TERM_GET_ERROR", TERM_UPDATE_ERROR: "TERM_UPDATE_ERROR", TERM_DELETE_ERROR: "TERM_DELETE_ERROR", TERMS_GET_ERROR: "TERMS_GET_ERROR", TERMS_SET_ERROR: "TERMS_SET_ERROR", // Sections SECTION_LIST_ERROR: "SECTION_LIST_ERROR", SECTION_CREATE_ERROR: "SECTION_CREATE_ERROR", SECTION_GET_ERROR: "SECTION_GET_ERROR", SECTION_UPDATE_ERROR: "SECTION_UPDATE_ERROR", SECTION_DELETE_ERROR: "SECTION_DELETE_ERROR", // Redirects REDIRECT_LIST_ERROR: "REDIRECT_LIST_ERROR", REDIRECT_CREATE_ERROR: "REDIRECT_CREATE_ERROR", REDIRECT_GET_ERROR: "REDIRECT_GET_ERROR", REDIRECT_UPDATE_ERROR: "REDIRECT_UPDATE_ERROR", REDIRECT_DELETE_ERROR: "REDIRECT_DELETE_ERROR", NOT_FOUND_LIST_ERROR: "NOT_FOUND_LIST_ERROR", NOT_FOUND_SUMMARY_ERROR: "NOT_FOUND_SUMMARY_ERROR", NOT_FOUND_CLEAR_ERROR: "NOT_FOUND_CLEAR_ERROR", NOT_FOUND_PRUNE_ERROR: "NOT_FOUND_PRUNE_ERROR", // Widgets WIDGET_AREA_LIST_ERROR: "WIDGET_AREA_LIST_ERROR", WIDGET_AREA_CREATE_ERROR: "WIDGET_AREA_CREATE_ERROR", WIDGET_AREA_GET_ERROR: "WIDGET_AREA_GET_ERROR", WIDGET_AREA_DELETE_ERROR: "WIDGET_AREA_DELETE_ERROR", WIDGET_CREATE_ERROR: "WIDGET_CREATE_ERROR", WIDGET_UPDATE_ERROR: "WIDGET_UPDATE_ERROR", WIDGET_DELETE_ERROR: "WIDGET_DELETE_ERROR", WIDGET_REORDER_ERROR: "WIDGET_REORDER_ERROR", WIDGET_COMPONENTS_ERROR: "WIDGET_COMPONENTS_ERROR", // Setup ALREADY_CONFIGURED: "ALREADY_CONFIGURED", INVALID_SEED: "INVALID_SEED", INVALID_REDIRECT: "INVALID_REDIRECT", SETUP_ERROR: "SETUP_ERROR", SETUP_STATUS_ERROR: "SETUP_STATUS_ERROR", SETUP_ADMIN_ERROR: "SETUP_ADMIN_ERROR", SETUP_VERIFY_ERROR: "SETUP_VERIFY_ERROR", DEV_BYPASS_ERROR: "DEV_BYPASS_ERROR", DEV_RESET_ERROR: "DEV_RESET_ERROR", MIGRATION_ERROR: "MIGRATION_ERROR", SEED_ERROR: "SEED_ERROR", // Settings SETTINGS_READ_ERROR: "SETTINGS_READ_ERROR", SETTINGS_UPDATE_ERROR: "SETTINGS_UPDATE_ERROR", EMAIL_SETTINGS_READ_ERROR: "EMAIL_SETTINGS_READ_ERROR", EMAIL_TEST_ERROR: "EMAIL_TEST_ERROR", // Search SEARCH_ERROR: "SEARCH_ERROR", STATS_ERROR: "STATS_ERROR", SUGGESTION_ERROR: "SUGGESTION_ERROR", REBUILD_ERROR: "REBUILD_ERROR", // Import WXR_ANALYZE_ERROR: "WXR_ANALYZE_ERROR", WXR_PREPARE_ERROR: "WXR_PREPARE_ERROR", WXR_IMPORT_ERROR: "WXR_IMPORT_ERROR", IMPORT_ERROR: "IMPORT_ERROR", REWRITE_ERROR: "REWRITE_ERROR", WP_PLUGIN_ANALYZE_ERROR: "WP_PLUGIN_ANALYZE_ERROR", WP_PLUGIN_IMPORT_ERROR: "WP_PLUGIN_IMPORT_ERROR", SSRF_BLOCKED: "SSRF_BLOCKED", PROBE_ERROR: "PROBE_ERROR", // Dashboard DASHBOARD_ERROR: "DASHBOARD_ERROR", DASHBOARD_STATS_ERROR: "DASHBOARD_STATS_ERROR", // Misc SNAPSHOT_ERROR: "SNAPSHOT_ERROR", TYPEGEN_ERROR: "TYPEGEN_ERROR", SITEMAP_ERROR: "SITEMAP_ERROR", NO_DB: "NO_DB", INVALID_REQUEST: "INVALID_REQUEST", UNKNOWN_ACTION: "UNKNOWN_ACTION", } as const; export type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode]; /** * OAuth RFC 6749 error codes. * * These MUST be lowercase per the RFC spec. Used only by OAuth token endpoints. * Separate from ErrorCode to prevent mixing conventions. */ export const OAuthErrorCode = { INVALID_GRANT: "invalid_grant", UNSUPPORTED_GRANT_TYPE: "unsupported_grant_type", EXPIRED_TOKEN: "expired_token", ACCESS_DENIED: "access_denied", AUTHORIZATION_PENDING: "authorization_pending", } as const; export type OAuthErrorCode = (typeof OAuthErrorCode)[keyof typeof OAuthErrorCode]; /** * Map a handler error code to an HTTP status code. * * Shared codes have explicit mappings. Domain-specific `*_ERROR` codes * (used in catch blocks via handleError) default to 500. Everything else * defaults to 400 (client error). */ export function mapErrorStatus(code: string | undefined): number { switch (code) { // 400 Bad Request case ErrorCode.VALIDATION_ERROR: case ErrorCode.INVALID_INPUT: case ErrorCode.INVALID_JSON: case ErrorCode.INVALID_CURSOR: case ErrorCode.MISSING_PARAM: case ErrorCode.INVALID_REQUEST: case ErrorCode.NOT_SUPPORTED: case ErrorCode.INVALID_SLUG: case ErrorCode.RESERVED_SLUG: case ErrorCode.INVALID_TYPE: case ErrorCode.NO_FILE: case ErrorCode.INVALID_STATE: case ErrorCode.INVALID_SEED: case ErrorCode.INVALID_REDIRECT: case ErrorCode.INVALID_TOKEN: case ErrorCode.INVALID_REVISION: case ErrorCode.INVALID_CODE: case ErrorCode.CHALLENGE_EXPIRED: case ErrorCode.EXPIRED_CODE: case ErrorCode.LAST_PASSKEY: case ErrorCode.PASSKEY_LIMIT: case ErrorCode.ADMIN_EXISTS: case ErrorCode.SETUP_COMPLETE: case ErrorCode.SELF_ROLE_CHANGE: case ErrorCode.SSRF_BLOCKED: case ErrorCode.UNKNOWN_ACTION: case ErrorCode.AMBIGUOUS_LOCALE: case ErrorCode.REORDER_MISMATCH: return 400; // 401 Unauthorized case ErrorCode.UNAUTHORIZED: case ErrorCode.NOT_AUTHENTICATED: return 401; // 403 Forbidden case ErrorCode.FORBIDDEN: case ErrorCode.CSRF_REJECTED: case ErrorCode.ACCOUNT_DISABLED: case ErrorCode.COMMENTS_DISABLED: case ErrorCode.COMMENTS_CLOSED: case ErrorCode.COMMENT_REJECTED: case ErrorCode.DOMAIN_NOT_ALLOWED: case ErrorCode.INSUFFICIENT_ROLE: case ErrorCode.INSUFFICIENT_SCOPE: case ErrorCode.INSUFFICIENT_PERMISSIONS: case ErrorCode.CAPABILITY_ESCALATION: case ErrorCode.ROUTE_VISIBILITY_ESCALATION: case ErrorCode.AUDIT_FAILED: return 403; // 404 Not Found case ErrorCode.NOT_FOUND: case ErrorCode.TABLE_NOT_FOUND: case ErrorCode.COLLECTION_NOT_FOUND: case ErrorCode.FILE_NOT_FOUND: case ErrorCode.NO_VERSION: case ErrorCode.AGGREGATOR_NOT_FOUND: return 404; // 409 Conflict case ErrorCode.CONFLICT: case ErrorCode.SLUG_CONFLICT: case ErrorCode.COLLECTION_EXISTS: case ErrorCode.FIELD_EXISTS: case ErrorCode.CREDENTIAL_EXISTS: case ErrorCode.EMAIL_IN_USE: case ErrorCode.USER_EXISTS: case ErrorCode.PLUGIN_ID_CONFLICT: case ErrorCode.ALREADY_INSTALLED: case ErrorCode.ALREADY_CONFIGURED: case ErrorCode.ALREADY_UP_TO_DATE: case ErrorCode.TRANSLATABLE_LOCKED: case ErrorCode.ENV_INCOMPATIBLE: return 409; // 410 Gone case ErrorCode.TOKEN_EXPIRED: return 410; // 422 Unprocessable Entity case ErrorCode.CHECKSUM_MISMATCH: case ErrorCode.INVALID_BUNDLE: case ErrorCode.BUNDLE_EXTRACT_FAILED: return 422; // 429 Too Many Requests case ErrorCode.RATE_LIMITED: return 429; // 500 Internal Server Error case ErrorCode.NOT_CONFIGURED: case ErrorCode.NO_STORAGE: case ErrorCode.NO_DB: case ErrorCode.STORAGE_NOT_CONFIGURED: case ErrorCode.EMAIL_NOT_CONFIGURED: return 500; // 501 Not Implemented case ErrorCode.NOT_IMPLEMENTED: return 501; // 502 Bad Gateway case ErrorCode.BUNDLE_DOWNLOAD_FAILED: case ErrorCode.AGGREGATOR_RESPONSE_INVALID: case ErrorCode.AGGREGATOR_HTTP_ERROR: return 502; // 503 Service Unavailable case ErrorCode.MARKETPLACE_UNAVAILABLE: case ErrorCode.MARKETPLACE_NOT_CONFIGURED: case ErrorCode.SANDBOX_NOT_AVAILABLE: return 503; // Domain-specific *_ERROR codes are catch-block codes -- always 500. // WARNING: If adding a new code that ends in _ERROR but represents a // client error (4xx), add it to an explicit case above or it will // be incorrectly mapped to 500. default: return code?.endsWith("_ERROR") ? 500 : 400; } }