fix: tell people when a snippet action fails - #488
Conversation
Every action on the snippets list sent its error to console.error and
nothing else:
export const handleUnknownError = (error: unknown) => {
console.error(error)
}
Activate, deactivate, trash, delete, restore, clone, export, priority and
all the bulk actions route failures there. Whatever goes wrong, a 403, a
500, a request that never left the browser, the row does not change and
nothing explains why. A failed action looks exactly like a click that
never registered.
That is bad on its own, and it is also why this class of problem cannot
be supported. Someone reports that snippets cannot be deleted, and there
is nothing for them to tell us and nothing for us to ask, because the
plugin discarded the one piece of information that would have identified
the cause.
Surface failures where the person is already looking. Actions now report
into a notice above the table, saying what did not happen, why, and that
nothing was changed. The HTTP status is included deliberately: requests
to the snippets API are blocked by security rules often enough that
"it did nothing" is impossible to diagnose without it.
Bulk actions previously discarded each snippet's error inside the loop.
They now count the failures and report once, with the number affected,
because a batch can partly succeed and "three of ten failed" is a very
different situation to nothing having happened.
Errors are still logged to the console, so the full object stays
available.
Prompted by a support report of snippets that could not be trashed,
deleted or disabled, where every theory was untestable because the
plugin reported nothing at all.
|
Verified in a combined 3.10.2 test build, installed from a zip on a clean WordPress 7.1 / PHP 8.1 site. Forcing a request to fail produces:
Confirmed on both the free and Pro builds. One thing for whoever merges this: it overlaps with #490. Both add a near-duplicate function to They combine cleanly by checking the session-expiry codes first and falling back to the status branch, with both call sites ( |
Draft, opened for the reasoning as much as the code. Prompted by this report of snippets that cannot be trashed, deleted or disabled.
The problem
Every action on the snippets list ends here:
Twelve call sites route failures into it: activate, deactivate, trash, delete, restore, clone, export, priority, the view toggle, the preview modal, and every bulk action. Whatever goes wrong — a 403, a 500, a request blocked before it left the browser — the row does not change and nothing explains why.
A failed action is indistinguishable from a click that never registered. That is the exact phrasing in the report: "they stay exactly the same and won't move", "shows no page refresh".
Why this matters beyond the UX
I spent a while trying to work out what was wrong on that user's site and ruled out, with tests:
no-cache, no-store, privateecho,header(), a forcedContent-Type, a PHP warning, and headers viasend_headers; all returned valid JSON. I confirmed his snippet genuinely does execute during REST requests first, so those were real testsEvery one of those was a guess, because the plugin discarded the only piece of information that would have identified the cause. There is nothing for the user to report and nothing for us to ask.
What this does
Failures are surfaced in a notice above the table, saying what did not happen, why, and that nothing was changed.
The HTTP status is included deliberately. Requests to the snippets API get blocked by security rules and firewalls often enough that "it did nothing" cannot be diagnosed without it, and asking people to open developer tools is a poor substitute for the plugin simply saying what happened.
Bulk actions previously discarded each snippet's error inside the loop. They now count failures and report once with the number affected, because a batch can partly succeed and "three of ten failed" is a very different situation to nothing having happened.
Errors are still logged to the console, so the full object remains available.
Verified
Simulated exactly that user's situation with an mu-plugin rejecting REST writes with 403, then clicked the activation toggle. Before, nothing at all. After:
That is a message a user can act on and a support thread can quote.
eslintclean across the project.Open questions for review
core-betaper the policy for shared changes, but there is an argument forcore, since the people who need it most are on released versions right now.Fixes #516