lxbme opened a new pull request, #3427: URL: https://github.com/apache/apisix-dashboard/pull/3427
**Why submit this pull request?** - [x] Bugfix - [ ] New feature provided - [ ] Improve performance - [ ] Backport patches **What changes will this PR take into?** ### Problem This addresses one item from the tracking issue #3417 (Error handling / resilience): > `PluginEditorDrawer` invokes `onSave` (async `mutateAsync`), then closes and resets **without awaiting** — failed saves lose user edits. Root cause: the drawer's `onSave` prop is typed `(props: PluginConfig) => void`, and the submit handler called it fire-and-forget, then synchronously ran `onClose()` and `methods.reset()`. The drawer has two call sites with different semantics: - the embedded plugins field (`FormItemPlugins/index.tsx`, used by route/service/consumer/global-rule/credential forms) passes a synchronous callback that only writes local form state — closing immediately is correct there; - the Plugin Metadata page passes `putMetadata.mutateAsync`, so the returned promise was silently discarded: the drawer closed as if the save had succeeded while the PUT was still in flight. When that PUT failed (network failure, 500, APISIX rejecting the metadata), the user's hand-edited JSON — plugin metadata configs are often long, e.g. log-format definitions — was already destroyed by `reset()`, and reopening the drawer showed the stale config from the query cache. An error toast (from the axios interceptor) appeared next to a drawer that had just closed as if everything went fine. ### Change Single component, `src/components/form-slice/FormItemPlugins/PluginEditorDrawer.tsx`: - widen `onSave` to `(props: PluginConfig) => void | Promise<unknown>` (both existing call sites already satisfy it, no caller changes); - make the submit handler async: `await onSave(...)`, and only on success run `onClose()` + `methods.reset()`; - on failure, swallow axios errors only — the interceptor owns their toasts (same pattern as `DeleteResourceBtn` in #3418) — and keep the drawer open with the edits intact so the save can be retried; non-axios errors still throw. The synchronous embedded call site is unaffected (`await undefined` is a no-op, the drawer still closes immediately). Bonus: `FormSubmitBtn` already binds `formState.isSubmitting`, so the Save button now shows a loading state during the request and double-clicks are prevented, with no extra code. ### Tests New e2e spec `e2e/tests/regression/plugin-metadata.drawer-keeps-edits-on-failed-save.spec.ts` (written first and verified failing against the old behavior): - seeds syslog plugin metadata via the Admin API, opens the metadata page, edits the JSON in the drawer; - forces the PUT to fail with a route-fulfilled 500 (`error_msg` payload, so the failure toast works independently of any interceptor changes); - asserts the failure toast appears **and** the drawer stays open with the edited value still in the Monaco editor; - lifts the fault and asserts the very same edit can be re-saved successfully (drawer closes, backend value verified via the Admin API). Also ran locally: both plugin_metadata CRUD suites, `plugin_editor_drawer.unsaved-changes`, `routes.empty-plugin-config` (embedded call-site coverage), and the full `e2e/tests/regression/` folder — all green. Manual testing additionally covered the responseless network-failure shape (request blocked at the browser level): edits are preserved there too. **Related issues** Part of #3417 (item: "PluginEditorDrawer invokes onSave then closes and resets without awaiting" under Error handling / resilience). Does **not** close the tracking issue. **Checklist:** - [x] Did you explain what problem does this PR solve? Or what new features have been added? - [x] Have you added corresponding test cases? - [ ] Have you modified the corresponding document? - [x] Is this PR backward compatible? If it is not backward compatible, please discuss on the mailing list first -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
