From cc3499798d2b55400097f04e3bb6aa357f8e9a31 Mon Sep 17 00:00:00 2001 From: CarolinaOP Date: Thu, 18 Dec 2025 22:20:52 +0000 Subject: [PATCH 1/2] Preserve snippet code_error in REST responses and show error notices --- src/js/hooks/useSubmitSnippet.ts | 35 +++++++++++++------ src/js/utils/snippets/objects.ts | 15 ++++++-- .../class-snippets-rest-controller.php | 6 ++-- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/js/hooks/useSubmitSnippet.ts b/src/js/hooks/useSubmitSnippet.ts index 2dc3530a..0c98ca59 100644 --- a/src/js/hooks/useSubmitSnippet.ts +++ b/src/js/hooks/useSubmitSnippet.ts @@ -86,7 +86,7 @@ export const useSubmitSnippet = (): UseSubmitSnippet => { const submitSnippet = useCallback(async (action: SubmitSnippetAction = SubmitSnippetAction.SAVE) => { setCurrentNotice(undefined) - const result = await (async (): Promise => { + const rawResult = await (async (): Promise => { try { const request: Snippet = { ...snippet, ...SUBMIT_ACTION_DELTA[action] } const response = await (0 === request.id ? snippetsAPI.create(request) : snippetsAPI.update(request)) @@ -100,25 +100,38 @@ export const useSubmitSnippet = (): UseSubmitSnippet => { const messages = isCondition(snippet) ? conditionMessages : snippetMessages - if (undefined === result || 'string' === typeof result) { + if (undefined === rawResult || 'string' === typeof rawResult) { const message = [ snippet.id ? messages.failedUpdate : messages.failedCreate, - result ?? __('The server did not send a valid response.', 'code-snippets') + rawResult ?? __('The server did not send a valid response.', 'code-snippets') ] setCurrentNotice(['error', message.filter(Boolean).join(' ')]) return undefined - } else { - setSnippet(createSnippetObject(result)) - setCurrentNotice(['updated', getSuccessNotice(snippet, result, action)]) + } - if (snippet.id && result.id) { - window.document.title = window.document.title.replace(snippetMessages.addNew, messages.edit) - window.history.replaceState({}, '', addQueryArgs(window.CODE_SNIPPETS?.urls.edit, { id: result.id })) - } + const updatedSnippet = createSnippetObject(rawResult) + setSnippet(updatedSnippet) - return result + if (updatedSnippet.code_error) { + setCurrentNotice([ + 'error', + __('Snippet could not be activated because the code contains an error. See details below.', 'code-snippets') + ]) + } else { + setCurrentNotice(['updated', getSuccessNotice(snippet, updatedSnippet, action)]) } + + if (snippet.id && updatedSnippet.id) { + window.document.title = window.document.title.replace(snippetMessages.addNew, messages.edit) + window.history.replaceState( + {}, + '', + addQueryArgs(window.CODE_SNIPPETS?.urls.edit, { id: updatedSnippet.id }) + ) + } + + return updatedSnippet }, [snippetsAPI, setIsWorking, setCurrentNotice, snippet, setSnippet]) return { submitSnippet } diff --git a/src/js/utils/snippets/objects.ts b/src/js/utils/snippets/objects.ts index f542ab64..81a2a211 100644 --- a/src/js/utils/snippets/objects.ts +++ b/src/js/utils/snippets/objects.ts @@ -13,7 +13,8 @@ const defaults: Omit = { network: isNetworkAdmin(), shared_network: null, priority: 10, - conditionId: 0 + conditionId: 0, + code_error: null } const isAbsInt = (value: unknown): value is number => @@ -33,6 +34,15 @@ export const parseSnippetObject = (fields: unknown): Snippet => { return result } + const codeError = + 'code_error' in fields && + Array.isArray(fields.code_error) && + 2 === fields.code_error.length && + 'string' === typeof fields.code_error[0] && + 'number' === typeof fields.code_error[1] + ? (fields.code_error as readonly [string, number]) + : undefined + return { ...result, ...'id' in fields && isAbsInt(fields.id) && { id: fields.id }, @@ -46,6 +56,7 @@ export const parseSnippetObject = (fields: unknown): Snippet => { ...'network' in fields && 'boolean' === typeof fields.network && { network: fields.network }, ...'shared_network' in fields && 'boolean' === typeof fields.shared_network && { shared_network: fields.shared_network }, ...'priority' in fields && 'number' === typeof fields.priority && { priority: fields.priority }, - ...'condition_id' in fields && isAbsInt(fields.condition_id) && { conditionId: fields.condition_id } + ...'condition_id' in fields && isAbsInt(fields.condition_id) && { conditionId: fields.condition_id }, + ...('code_error' in fields && { code_error: codeError ?? result.code_error }) } } diff --git a/src/php/rest-api/class-snippets-rest-controller.php b/src/php/rest-api/class-snippets-rest-controller.php index bf37e60b..d1b9b6b7 100644 --- a/src/php/rest-api/class-snippets-rest-controller.php +++ b/src/php/rest-api/class-snippets-rest-controller.php @@ -325,12 +325,12 @@ public function update_item( $request ) { ); } - $item = $this->prepare_item_for_database( $request, $snippet ); + $item = $this->prepare_item_for_database( $request, $snippet ); $result = save_snippet( $item ); if ( $result ) { - $request->set_param( 'id', $result->id ); - return $this->get_item( $request ); + $data = $this->prepare_item_for_response( $result, $request ); + return rest_ensure_response( $data ); } return new WP_Error( From 34826acadf3ff8662ebda6f76633db07d0528040 Mon Sep 17 00:00:00 2001 From: CarolinaOP Date: Thu, 18 Dec 2025 23:13:38 +0000 Subject: [PATCH 2/2] simplified --- src/js/hooks/useSubmitSnippet.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/js/hooks/useSubmitSnippet.ts b/src/js/hooks/useSubmitSnippet.ts index 0c98ca59..bb074df7 100644 --- a/src/js/hooks/useSubmitSnippet.ts +++ b/src/js/hooks/useSubmitSnippet.ts @@ -86,7 +86,7 @@ export const useSubmitSnippet = (): UseSubmitSnippet => { const submitSnippet = useCallback(async (action: SubmitSnippetAction = SubmitSnippetAction.SAVE) => { setCurrentNotice(undefined) - const rawResult = await (async (): Promise => { + const result = await (async (): Promise => { try { const request: Snippet = { ...snippet, ...SUBMIT_ACTION_DELTA[action] } const response = await (0 === request.id ? snippetsAPI.create(request) : snippetsAPI.update(request)) @@ -100,17 +100,17 @@ export const useSubmitSnippet = (): UseSubmitSnippet => { const messages = isCondition(snippet) ? conditionMessages : snippetMessages - if (undefined === rawResult || 'string' === typeof rawResult) { + if (undefined === result || 'string' === typeof result) { const message = [ snippet.id ? messages.failedUpdate : messages.failedCreate, - rawResult ?? __('The server did not send a valid response.', 'code-snippets') + result ?? __('The server did not send a valid response.', 'code-snippets') ] setCurrentNotice(['error', message.filter(Boolean).join(' ')]) return undefined } - const updatedSnippet = createSnippetObject(rawResult) + const updatedSnippet = createSnippetObject(result) setSnippet(updatedSnippet) if (updatedSnippet.code_error) {