Add middleware for displaying API errors as notices

[MAILPOET-4523]
This commit is contained in:
Jan Jakes
2022-09-06 14:05:11 +02:00
committed by John Oleksowicz
parent becf82ef8c
commit c8c07c470d
5 changed files with 58 additions and 6 deletions

View File

@@ -5,6 +5,16 @@ export * from './hooks';
const apiUrl = `${api.root}/mailpoet/v1/automation/`;
export type ApiError = {
code?: string;
message?: string;
data?: {
status?: number;
details?: Error;
params?: Record<string, string>;
};
};
export const initializeApi = () => {
apiFetch.use(apiFetch.createRootURLMiddleware(apiUrl));
apiFetch.use(apiFetch.createNonceMiddleware(api.nonce));

View File

@@ -0,0 +1,36 @@
import apiFetch, { APIFetchOptions } from '@wordpress/api-fetch';
import { dispatch, StoreDescriptor } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
import { ApiError } from '../api';
export const registerApiErrorHandler = (): void =>
apiFetch.use(
async (
options: APIFetchOptions,
next: (nextOptions: APIFetchOptions) => Promise<unknown>,
) => {
try {
const result = await next(options);
return result;
} catch (error) {
const errorObject = error as ApiError;
const status = errorObject.data?.status;
if (status && status >= 400 && status < 500) {
const message = errorObject.message;
void dispatch(noticesStore as StoreDescriptor).createErrorNotice(
message ?? __('An unknown error occurred.', 'mailpoet'),
{ explicitDismiss: true },
);
return undefined;
}
void dispatch(noticesStore as StoreDescriptor).createErrorNotice(
__('An unknown error occurred.', 'mailpoet'),
{ explicitDismiss: true },
);
throw error;
}
},
);

View File

@@ -12,7 +12,6 @@ import { Separator } from './separator';
import { Step } from './step';
import { Step as StepData } from './types';
import { InserterPopover } from '../inserter-popover';
import { EditorNotices } from '../notices';
import { storeName } from '../../store';
import { AddTrigger } from './add-trigger';
@@ -95,7 +94,6 @@ export function Workflow(): JSX.Element {
return (
<WorkflowCompositeContext.Provider value={compositeState}>
<EditorNotices />
<Composite
state={compositeState}
role="tree"

View File

@@ -13,6 +13,7 @@ import { addQueryArgs } from '@wordpress/url';
import { Header } from './components/header';
import { InserterSidebar } from './components/inserter-sidebar';
import { KeyboardShortcuts } from './components/keyboard-shortcuts';
import { EditorNotices } from './components/notices';
import { Sidebar } from './components/sidebar';
import { Workflow } from './components/workflow';
import { createStore, storeName } from './store';
@@ -21,6 +22,7 @@ import { initialize as initializeCoreIntegration } from '../integrations/core';
import { initialize as initializeMailPoetIntegration } from '../integrations/mailpoet';
import { MailPoet } from '../../mailpoet';
import { LISTING_NOTICE_PARAMETERS } from '../listing/workflow-listing-notices';
import { registerApiErrorHandler } from './api-error-handler';
// See:
// https://github.com/WordPress/gutenberg/blob/9601a33e30ba41bac98579c8d822af63dd961488/packages/edit-post/src/components/layout/index.js
@@ -79,7 +81,12 @@ function Editor(): JSX.Element {
)
}
header={<Header showInserterToggle={showInserterSidebar} />}
content={<Workflow />}
content={
<>
<EditorNotices />
<Workflow />
</>
}
sidebar={<ComplementaryArea.Slot scope={storeName} />}
secondarySidebar={
showInserterSidebar && isInserterOpened ? <InserterSidebar /> : null
@@ -96,6 +103,7 @@ window.addEventListener('DOMContentLoaded', () => {
const root = document.getElementById('mailpoet_automation_editor');
if (root) {
registerApiErrorHandler();
initializeApi();
initializeCoreIntegration();
initializeMailPoetIntegration();

View File

@@ -54,12 +54,12 @@ export function* save() {
const data = yield apiFetch({
path: `/workflows/${workflow.id}`,
method: 'PUT',
data: workflow,
data: { ...workflow },
});
return {
type: 'SAVE',
workflow: data.data,
workflow: data?.data ?? workflow,
} as const;
}
@@ -76,7 +76,7 @@ export function* activate() {
return {
type: 'ACTIVATE',
workflow: data.data,
workflow: data?.data ?? workflow,
} as const;
}