Skip to content

Show the server's own reason when adding a batch fails - #332

Merged
vikrantwiz02 merged 3 commits into
FusionIIIT:acad-mainfrom
vikrantwiz02:fix/api-error-messages
Oct 7, 2026
Merged

vikrantwiz02 merged 3 commits into
FusionIIIT:acad-mainfrom
vikrantwiz02:fix/api-error-messages

Conversation

@vikrantwiz02

Copy link
Copy Markdown
Member

Summary

  • Added a shared apiError.js helper that reads a server error response consistently (message/detail/validation fields), and wired it into the Academic module's forms/dashboards so they surface the server's actual reason instead of a generic failure message.
  • Admin_add_batch_form.jsx now shows the real validation error (e.g. duplicate batch) coming back from admin_add_batch instead of a generic "failed to add batch".
  • Cleared the pre-existing lint errors that were blocking the pre-commit hook in gradeSheetPdf.js/gradeSheetTemplate.js (new-cap, no-promise-executor-return, no-plusplus, no-await-in-loop).

Test plan

  • npx eslint clean on all touched files
  • npx vitest run src/helper/apiError.test.js — 11/11 passing
  • npm run build

The Add Batch form reported "Request failed with status code 400", which is
axios's own message and says nothing about what went wrong. The backend had
already sent the reason: create_batch answers with
{success: false, message: "Missing required fields: ..."} or "Invalid
curriculum ID: N. Curriculum not found or not working." That text arrives in
error.response.data and was being discarded.

getApiErrorMessage reads it, covering the shapes these APIs actually return:
message, error, detail, non_field_errors, DRF per-field arrays and a bare
string, ignoring an HTML error page. When the body says nothing it falls back
to the meaning of the status, and a request that never reached the server is
reported as such rather than as a failed one.

Two other faults in the same handler:

setError on a failed submit replaced the whole page with a red line, because
that state is the load-failure screen. A rejected submit destroyed the form
and everything typed into it. The toast is enough.

The non-message branch called response.json() on an axios response, which has
no such method and would have thrown.

Also drops an unused MultiSelect import the lint hook rejects.

11 unit tests on the reader.
Every call site here already tried to pull the server's explanation out of a
failed request, but each one checked a different subset of keys: some read
error, some detail, some both, some added message. An endpoint answering with
a key its caller does not check falls through to axios's own
"Request failed with status code 400", which is what the user then sees. The
dev backend returns {"error": ...} for a permission failure, so the files
checking only detail showed the useless line.

38 call sites across 13 files now go through getApiErrorMessage, which checks
every shape the APIs return. The existing fallback strings are preserved as
its second argument, so a message like "Drop failed" still appears when the
server offers nothing.

No behaviour change beyond the messages themselves.
eslint . failed on acad-main with 11 errors, so the pre-commit hook rejected
every commit regardless of what it contained. None of the fixes change
behaviour:

jsPDF is imported as JsPDF in the two PDF builders, since new-cap wants a
constructor to start with a capital. tableWidth and academicTableWidth in the
receipt were computed and never read.

The three setTimeout promises in the grade sheet builder returned the timer id
out of the executor, which no-promise-executor-return flags; the executor body
is braced now and resolves the same way.

The page render loop is indexed rather than for..of. Its await is sequential on
purpose, because each page is drawn onto the document in order, so that one
rule is disabled on the line rather than restructured.

Two post-increments became += 1. The one in the test console formatter read
and incremented in the same expression, so the counter starts at 0 and
increments before the read to keep the same argument order.

eslint . is clean, 478 tests pass, build succeeds.
@vikrantwiz02
vikrantwiz02 merged commit 3c803d0 into FusionIIIT:acad-main Oct 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant