| @@ -1,3 +1,63 @@ | ||
| 1 | +import { __ } from '@wordpress/i18n' | |
| 2 | +import { isAxiosError, isCancel } from 'axios' | |
| 3 | + | |
| 1 | 4 | export const handleUnknownError = (error: unknown) => { |
| 2 | 5 | console.error(error) |
| 6 | +} | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * Whether a rejection came from the caller aborting the request rather than | |
| 10 | + * from a failure — axios rejects cancelled requests with no response attached, | |
| 11 | + * so these must not be surfaced to the user as errors. | |
| 12 | + */ | |
| 13 | +export const isAbortError = (error: unknown): boolean => | |
| 14 | + isCancel(error) || error instanceof DOMException && 'AbortError' === error.name | |
| 15 | + | |
| 16 | +export const unpackErrorResponse = (error: unknown): string => { | |
| 17 | + if (isAxiosError(error)) { | |
| 18 | + if (error.response) { | |
| 19 | + const responseData: unknown = error.response.data | |
| 20 | + | |
| 21 | + if (responseData && 'object' === typeof responseData && 'message' in responseData) { | |
| 22 | + return String(responseData.message) | |
| 23 | + } | |
| 24 | + } | |
| 25 | + | |
| 26 | + return error.message | |
| 27 | + } | |
| 28 | + | |
| 29 | + return __('An unknown error occurred.', 'code-snippets') | |
| 30 | +} | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * Explain a failed request in terms the reader can act on. | |
| 34 | + * | |
| 35 | + * An expired session is the common case worth naming: the snippet editor is a | |
| 36 | + * screen people leave open, and once the session lapses WordPress rejects every | |
| 37 | + * write with a 403 that says only "Cookie check failed". Reporting the raw | |
| 38 | + * status left people believing the plugin had ignored them. | |
| 39 | + */ | |
| 40 | +export const describeRequestError = (error: unknown): string => { | |
| 41 | + if (!isAxiosError(error)) { | |
| 42 | + return unpackErrorResponse(error) | |
| 43 | + } | |
| 44 | + | |
| 45 | + if (!error.response) { | |
| 46 | + return __( | |
| 47 | + 'The request did not reach your site. Check your connection, or whether a security plugin is blocking it.', | |
| 48 | + 'code-snippets' | |
| 49 | + ) | |
| 50 | + } | |
| 51 | + | |
| 52 | + const data: unknown = error.response.data | |
| 53 | + const code = data && 'object' === typeof data && 'code' in data ? String(data.code) : '' | |
| 54 | + | |
| 55 | + if ('rest_cookie_invalid_nonce' === code || 'rest_not_logged_in' === code) { | |
| 56 | + return __( | |
| 57 | + 'You have been signed out, so nothing was saved. Sign in again in another tab, then save. Your changes are still here.', | |
| 58 | + 'code-snippets' | |
| 59 | + ) | |
| 60 | + } | |
| 61 | + | |
| 62 | + return unpackErrorResponse(error) | |
| 3 | 63 | } |