From 23bb523dea1e3030af979e0ee7798174702f84d3 Mon Sep 17 00:00:00 2001 From: Peter Hudec Date: Fri, 8 Mar 2024 11:31:53 +0000 Subject: [PATCH] Task now keeps the rejected value as `error` --- .../companies/apps/add-company/client/tasks.js | 2 +- .../apps/details-form/client/tasks.js | 4 +++- src/client/components/AccessDenied/index.jsx | 2 ++ src/client/components/ContactForm/tasks.js | 8 +------- src/client/components/Task/index.jsx | 11 ++++++++++- src/client/components/Task/saga.js | 4 +++- src/client/components/Task/utils.js | 16 ++++++++-------- .../CompanyExports/ExportCountriesEdit/index.jsx | 12 +++++------- src/client/modules/ExportWins/Review/index.jsx | 2 +- .../Interactions/ESSInteractionDetails/index.jsx | 1 + .../cypress/specs/ExportWins/Review.cy.jsx | 2 +- test/sandbox/routes/v4/export-win/export-win.js | 3 +++ 12 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/apps/companies/apps/add-company/client/tasks.js b/src/apps/companies/apps/add-company/client/tasks.js index 5508ced83d2..0602186b8ca 100644 --- a/src/apps/companies/apps/add-company/client/tasks.js +++ b/src/apps/companies/apps/add-company/client/tasks.js @@ -14,7 +14,7 @@ export const createCompany = ({ csrfToken, ...values }) => { return axios .post(postUrl, values) .catch((err) => { - return Promise.reject(err.response.data.error.message) + return Promise.reject(err.response.data.error.message[0]) }) .then((response) => response.data) } diff --git a/src/apps/interactions/apps/details-form/client/tasks.js b/src/apps/interactions/apps/details-form/client/tasks.js index 2d7f88c9601..89e58246345 100644 --- a/src/apps/interactions/apps/details-form/client/tasks.js +++ b/src/apps/interactions/apps/details-form/client/tasks.js @@ -354,7 +354,9 @@ export function saveInteraction({ values, companyIds, referralId }) { .catch((e) => { // Accounts for non-standard API error on contacts field const contactsError = e.response?.data?.contacts[0] - return contactsError ? Promise.reject(contactsError) : catchApiError(e) + return contactsError + ? Promise.reject(contactsError) + : catchApiError(e).message }) } diff --git a/src/client/components/AccessDenied/index.jsx b/src/client/components/AccessDenied/index.jsx index 3b984f0be31..073cad84459 100644 --- a/src/client/components/AccessDenied/index.jsx +++ b/src/client/components/AccessDenied/index.jsx @@ -3,6 +3,8 @@ import React from 'react' import DefaultLayout from '../Layout/DefaultLayout' const AccessDenied = ({ breadcrumbs }) => ( + // FIXME: This shouldn't DefaultLayout as it can appear anywhere in a page in which case + // it completely breaks the layout. { values.company = { id: values.company.id } return request(contactId ? `${endpoint}/${contactId}` : endpoint, values) - .catch((e) => { - if (e?.errors) { - return { data: e } - } else { - return Promise.reject(e.message) - } - }) + .catch((e) => Promise.reject(e?.data?.email?.[0] || e.message)) .then((response) => { return response.data }) diff --git a/src/client/components/Task/index.jsx b/src/client/components/Task/index.jsx index 4521e8a5468..2aa742f4ce1 100644 --- a/src/client/components/Task/index.jsx +++ b/src/client/components/Task/index.jsx @@ -52,8 +52,14 @@ const startOnRenderPropTypes = { * @typedef Task * @property {'progress' | 'error'} status - The current status of the task * @property {Boolean} progress - Whether the task is in progress - * @property {Boolean} error - Whether the task is in error state + * @property {Boolean} isError - Whether the task is in error state * @property {(name, id, StartOptions) => void} start - Starts a task. + * @property {any} [payload=undefined] - The value of the payload with which the task was started. + * @property {any} [error=undefined] - The value with wich the task rejected + * @property {string} [errorMessage=undefined] - Error message extracted from {error.message}. + * @property {string} [onSuccessDispatch=undefined] - Action that will be dispatched when the task resolves + * @property {() => void} [dismissError=undefined] - When when the task is in `state === 'error'` + * will reset the tasks state. */ /** @@ -245,6 +251,7 @@ Task.Status = ({ errorMessage, onSuccessDispatch, dismissError, + error, } = getTask(name, id) const retry = () => @@ -263,12 +270,14 @@ Task.Status = ({ progress && renderProgress({ message: progressMessage, noun })} {isError && + // FIXME: This is shouldn't be done here and it shouldn't be done this way (errorMessage === 'You do not have permission to perform this action.' ? ( ) : ( renderError({ noun, + error, errorMessage, retry: !noRetry && retry, dismiss: !noDismiss && dismissError, diff --git a/src/client/components/Task/saga.js b/src/client/components/Task/saga.js index a91deef30f8..ec095351e25 100644 --- a/src/client/components/Task/saga.js +++ b/src/client/components/Task/saga.js @@ -47,7 +47,9 @@ function* startTask(task, action) { type: TASK__ERROR, id, name, - errorMessage: error, + error, + // FIXME: This should be handled on the renderError level + errorMessage: typeof error === 'string' ? error : error.message, }) } } diff --git a/src/client/components/Task/utils.js b/src/client/components/Task/utils.js index 6136c8f0d23..94cceb23c1f 100644 --- a/src/client/components/Task/utils.js +++ b/src/client/components/Task/utils.js @@ -20,17 +20,17 @@ export const delay = curry((duration, task, payload) => ) export const catchApiError = ({ response, message }) => - Promise.reject( - response?.data?.detail || + Promise.reject({ + message: + response?.data?.detail || response?.text || response?.data?.non_field_errors || - (response?.data && { - errors: response.data, - httpStatusCode: response.status, - }) || response?.statusText || - message - ) + response.data || + message, + data: response.data, + httpStatusCode: response.status, + }) /** * A custom Axios instance for easy access to the `/api-proxy` endpoint. diff --git a/src/client/modules/Companies/CompanyExports/ExportCountriesEdit/index.jsx b/src/client/modules/Companies/CompanyExports/ExportCountriesEdit/index.jsx index 681c524ef98..579f2d4dfe0 100644 --- a/src/client/modules/Companies/CompanyExports/ExportCountriesEdit/index.jsx +++ b/src/client/modules/Companies/CompanyExports/ExportCountriesEdit/index.jsx @@ -29,27 +29,25 @@ const StyledP = styled.p` margin: 0; ` -function ErrorHandler({ errorMessage }) { +function ErrorHandler({ error }) { return ( <> - {errorMessage[API_ERROR] && ( + {error[API_ERROR] && ( - - {errorMessage[API_ERROR]} - + {error[API_ERROR]} )} - {errorMessage[API_WARN] && ( + {error[API_WARN] && ( Export countries could not be saved, try again later. - {errorMessage[API_WARN]} + {error[API_WARN]} )} diff --git a/src/client/modules/ExportWins/Review/index.jsx b/src/client/modules/ExportWins/Review/index.jsx index c8aef28cf21..4751decc22d 100644 --- a/src/client/modules/ExportWins/Review/index.jsx +++ b/src/client/modules/ExportWins/Review/index.jsx @@ -27,7 +27,7 @@ import ThankYou from './ThankYou' const FORM_ID = 'export-wins-customer-feedback' const NotFound = (props) => - props.errorMessage?.httpStatusCode === 404 ? ( + props.error?.httpStatusCode === 404 ? ( <>

The link you used has expired

diff --git a/src/client/modules/Interactions/ESSInteractionDetails/index.jsx b/src/client/modules/Interactions/ESSInteractionDetails/index.jsx index a1a3f01a51a..f4941db1079 100644 --- a/src/client/modules/Interactions/ESSInteractionDetails/index.jsx +++ b/src/client/modules/Interactions/ESSInteractionDetails/index.jsx @@ -45,6 +45,7 @@ const ESSInteractionDetails = ({ breadcrumbs={breadcrumbs} useReactRouter={true} > + {/* TODO: Use Resource */} { it("should render default error view if the review couldn't be loaded for", () => { const Provider = createTestProvider({ - 'Export Win Review': () => Promise.reject(), + 'Export Win Review': () => Promise.reject({}), }) cy.mount( diff --git a/test/sandbox/routes/v4/export-win/export-win.js b/test/sandbox/routes/v4/export-win/export-win.js index becc56d0ad1..1c9f4e6a962 100644 --- a/test/sandbox/routes/v4/export-win/export-win.js +++ b/test/sandbox/routes/v4/export-win/export-win.js @@ -142,6 +142,9 @@ export const getExportWinReview = (req, res) => { if (req.params.token === 'non-existent') { return res.status(404).json({ detail: 'Not found' }) } + if (req.params.token === 'server-error') { + return res.status(500).json({ detail: 'Server error' }) + } res.json({ win: fakeExportWin(), company_contact: {