[Bug 43516] New: Harden the frontend HttpClient and add a shared API error formatter
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Bug ID: 43516 Summary: Harden the frontend HttpClient and add a shared API error formatter Initiative type: --- Sponsorship --- status: Product: Koha Version: Main Hardware: All OS: All Status: NEW Severity: enhancement Priority: P5 - low Component: Architecture, internals, and plumbing Assignee: koha-bugs@lists.koha-community.org Reporter: martin.renvoize@openfifth.co.uk QA Contact: testopia@bugs.koha-community.org Blocks: 41129 Target Milestone: --- This patch hardens the shared frontend HttpClient (both the plain fetch/http-client.js used by most Vue API clients, and the Vue-composable variant in vue/fetch/http-client.js) against malformed and unreachable API responses, and adds a generic, translated API error formatter. Specifically: - Guard against malformed JSON in responses (a truncated body, a proxy error page, a session-expired redirect) instead of letting the parse error surface as the failure. - Preserve the HTTP status and Koha error_code on thrown errors so callers can branch on them. - Add a per-request config object (config.signal to cancel the underlying fetch via AbortController, config.suppressDefaultErrorDialog for callers that present their own error UI). - Add fetch/api-error.js: a small, translated formatApiError() helper that turns a thrown API error into a user-facing message (401, 403, network-unreachable, and generic fallback cases). This is generic frontend infrastructure with no feature-specific behaviour; it's split out from bug 41129 (booking workflows) because several later patches depend on it and it benefits from independent review. Test plan: 1. Run: yarn cypress run --component --browser electron --spec 't/cypress/component/HttpClient_spec.ts,t/cypress/component/VueHttpClient_spec.ts,t/cypress/component/fetch/api-error_spec.ts' 2. Verify all specs pass. Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=41129 [Bug 41129] Migrate place_booking.js to a Vue island. -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 --- Comment #1 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205526 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205526&action=edit Bug 43516: Harden HttpClient against malformed and unreachable API responses Guard against malformed JSON in http-client responses (a truncated body, a proxy error page, a session-expired redirect) instead of letting the parse error surface as the failure. Preserve the HTTP status and Koha error_code on thrown errors so callers can branch on them. Add a per-request config object to both the plain fetch/http-client.js and the Vue-composable vue/fetch/http-client.js: - config.signal cancels the underlying fetch via AbortController. - config.suppressDefaultErrorDialog lets callers that present their own error UI skip the page-level error dialog; the error is still thrown with status/code attached. Test plan: 1. Run: yarn cypress run --component --browser electron --spec 't/cypress/component/HttpClient_spec.ts,t/cypress/component/VueHttpClient_spec.ts' 2. Verify all specs pass. -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 --- Comment #2 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205527 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205527&action=edit Bug 43516: Add a shared, translated API error formatter Add fetch/api-error.js: a small formatApiError() helper that turns a thrown API error into a translated, user-facing message. Recognises 401 (session expired), 403 (not authorized), a network failure (fetch itself never reaching the server), and falls back to a generic message carrying the raw error text when available. Test plan: 1. Run: yarn cypress run --component --browser electron --spec 't/cypress/component/fetch/api-error_spec.ts' 2. Verify all specs pass. -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jacob.omara@openfifth.co.uk | |, | |jonathan.druart@gmail.com, | |matt.blenkinsop@openfifth.c | |o.uk, me@paulderscheid.xyz -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #205526|0 |1 is obsolete| | Attachment #205527|0 |1 is obsolete| | -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 --- Comment #3 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205544 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205544&action=edit Bug 43516: Harden HttpClient against malformed and unreachable API responses Guard against malformed JSON in http-client responses (a truncated body, a proxy error page, a session-expired redirect) instead of letting the parse error surface as the failure. Preserve the HTTP status and Koha error_code on thrown errors so callers can branch on them. Add a per-request config object to both the plain fetch/http-client.js and the Vue-composable vue/fetch/http-client.js: - config.signal cancels the underlying fetch via AbortController. - config.suppressDefaultErrorDialog lets callers that present their own error UI skip the page-level error dialog; the error is still thrown with status/code attached. Split out from bug 41129 (booking workflows), where this was introduced across three patches, into its own bug as generic frontend infrastructure. Test plan: 1. Run: yarn cypress run --component --browser electron --spec 't/cypress/component/HttpClient_spec.ts,t/cypress/component/VueHttpClient_spec.ts' 2. Verify all specs pass. Co-authored-by: Paul Derscheid <paul.derscheid@lmscloud.de> Co-authored-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> Sponsored-by: Büchereizentrale Schleswig-Holstein <https://www.bz-sh.de/> Assisted-by: Opus 4.8 (Anthropic) Assisted-by: GPT 5.6 (OpenAI) Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> Signed-off-by: Jacob O'Mara <jacob.omara@openfifth.co.uk> Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de> -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 --- Comment #4 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205545 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205545&action=edit Bug 43516: Add a shared, translated API error formatter Add fetch/api-error.js: a small formatApiError() helper that turns a thrown API error into a translated, user-facing message. Recognises 401 (session expired), 403 (not authorized), a network failure (fetch itself never reaching the server), and falls back to a generic message carrying the raw error text when available. Split out from bug 41129 (booking workflows) as generic frontend infrastructure. Test plan: 1. Run: yarn cypress run --component --browser electron --spec 't/cypress/component/fetch/api-error_spec.ts' 2. Verify all specs pass. Co-authored-by: Jacob O'Mara <jacob.omara@openfifth.co.uk> Co-authored-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> Sponsored-by: Büchereizentrale Schleswig-Holstein <https://www.bz-sh.de/> Assisted-by: Opus 4.8 (Anthropic) Assisted-by: GPT 5.6 (OpenAI) Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> Signed-off-by: Jacob O'Mara <jacob.omara@openfifth.co.uk> Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de> -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |Needs Signoff -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|Needs Signoff |Signed Off -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Assignee|koha-bugs@lists.koha-commun |jacob.omara@openfifth.co.uk |ity.org | -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- QA Contact|testopia@bugs.koha-communit |matt.blenkinsop@openfifth.c |y.org |o.uk -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Paul Derscheid <paul.derscheid@lmscloud.de> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |paul.derscheid@lmscloud.de -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 --- Comment #5 from Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> --- Comment on attachment 205544 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205544 Bug 43516: Harden HttpClient against malformed and unreachable API responses Review of attachment 205544: --> (https://bugs.koha-community.org/bugzilla3/page.cgi?id=splinter.html&bug=43516&attachment=205544) ----------------------------------------------------------------- Couple of comments in the review. The tests also fail without 43517, should this be a dependency or does a change need merging back into this bug? (It throws on a .format() call that 43517 adds into the cypress config) ::: koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js @@ +69,3 @@
) { let res, error; + void mark_submitting;
Is this here for linting errors? If so I think we need a comment or use an eslint-disable comment instead of the void as it might be confusing @@ +117,5 @@
}); } + return response.json().catch(() => { + const err = new Error( + "Invalid response from server: could not parse JSON"
Not translatable - needs wrapping -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|Signed Off |Failed QA -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 --- Comment #6 from Paul Derscheid <paul.derscheid@lmscloud.de> --- Good morning Matt, good finds. I remember setting `void mark_submitting` to silence the linter, yeah. And the string needs to be translatable, yeah :D -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 --- Comment #7 from Paul Derscheid <paul.derscheid@lmscloud.de> --- Created attachment 205673 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205673&action=edit Bug 43516: (follow-up) Translate the malformed-response error Test plan: 1. Run: yarn cypress run --component --browser electron --spec 't/cypress/component/HttpClient_spec.ts,t/cypress/component/VueHttpClient_spec.ts' 2. Verify all specs pass. -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 --- Comment #8 from Paul Derscheid <paul.derscheid@lmscloud.de> --- Created attachment 205674 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205674&action=edit Bug 43516: (follow-up) Replace void mark_submitting with an eslint-disable comment Test plan: 1. Run: yarn eslint koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js 2. Verify no no-unused-vars error is reported for mark_submitting. -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Paul Derscheid <paul.derscheid@lmscloud.de> changed: What |Removed |Added ---------------------------------------------------------------------------- Depends on| |43517 Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43517 [Bug 43517] Enable vue-tsc type checking and shared Cypress component-test shims -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 --- Comment #9 from Paul Derscheid <paul.derscheid@lmscloud.de> --- I made this bug depend on 43517 because of string format btw. -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Sponsorship status|--- |Sponsored Status|Failed QA |Passed QA Comma delimited| |Büchereizentrale list of Sponsors| |Schleswig-Holstein | |<https://www.bz-sh.de/> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #205544|0 |1 is obsolete| | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #205545|0 |1 is obsolete| | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #205673|0 |1 is obsolete| | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #205674|0 |1 is obsolete| | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 --- Comment #10 from Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> --- Created attachment 206239 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=206239&action=edit Bug 43516: Harden HttpClient against malformed and unreachable API responses Guard against malformed JSON in http-client responses (a truncated body, a proxy error page, a session-expired redirect) instead of letting the parse error surface as the failure. Preserve the HTTP status and Koha error_code on thrown errors so callers can branch on them. Add a per-request config object to both the plain fetch/http-client.js and the Vue-composable vue/fetch/http-client.js: - config.signal cancels the underlying fetch via AbortController. - config.suppressDefaultErrorDialog lets callers that present their own error UI skip the page-level error dialog; the error is still thrown with status/code attached. Split out from bug 41129 (booking workflows), where this was introduced across three patches, into its own bug as generic frontend infrastructure. Test plan: 1. Run: yarn cypress run --component --browser electron --spec 't/cypress/component/HttpClient_spec.ts,t/cypress/component/VueHttpClient_spec.ts' 2. Verify all specs pass. Co-authored-by: Paul Derscheid <paul.derscheid@lmscloud.de> Co-authored-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> Sponsored-by: Büchereizentrale Schleswig-Holstein <https://www.bz-sh.de/> Assisted-by: Opus 4.8 (Anthropic) Assisted-by: GPT 5.6 (OpenAI) Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> Signed-off-by: Jacob O'Mara <jacob.omara@openfifth.co.uk> Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de> Signed-off-by: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 --- Comment #11 from Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> --- Created attachment 206240 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=206240&action=edit Bug 43516: Add a shared, translated API error formatter Add fetch/api-error.js: a small formatApiError() helper that turns a thrown API error into a translated, user-facing message. Recognises 401 (session expired), 403 (not authorized), a network failure (fetch itself never reaching the server), and falls back to a generic message carrying the raw error text when available. Split out from bug 41129 (booking workflows) as generic frontend infrastructure. Test plan: 1. Run: yarn cypress run --component --browser electron --spec 't/cypress/component/fetch/api-error_spec.ts' 2. Verify all specs pass. Co-authored-by: Jacob O'Mara <jacob.omara@openfifth.co.uk> Co-authored-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> Sponsored-by: Büchereizentrale Schleswig-Holstein <https://www.bz-sh.de/> Assisted-by: Opus 4.8 (Anthropic) Assisted-by: GPT 5.6 (OpenAI) Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> Signed-off-by: Jacob O'Mara <jacob.omara@openfifth.co.uk> Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de> Signed-off-by: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 --- Comment #12 from Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> --- Created attachment 206241 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=206241&action=edit Bug 43516: (follow-up) Translate the malformed-response error Test plan: 1. Run: yarn cypress run --component --browser electron --spec 't/cypress/component/HttpClient_spec.ts,t/cypress/component/VueHttpClient_spec.ts' 2. Verify all specs pass. Signed-off-by: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43516 --- Comment #13 from Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> --- Created attachment 206242 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=206242&action=edit Bug 43516: (follow-up) Replace void mark_submitting with an eslint-disable comment Test plan: 1. Run: yarn eslint koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js 2. Verify no no-unused-vars error is reported for mark_submitting. Signed-off-by: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
participants (1)
-
bugzilla-daemon@bugs.koha-community.org