Skip to content

fix: simple form zombie state when submission fails#190

Open
mushrafmim wants to merge 2 commits intoOpenNSW:mainfrom
mushrafmim:fix/117-simple-form-zombie-state-when-submission-fails
Open

fix: simple form zombie state when submission fails#190
mushrafmim wants to merge 2 commits intoOpenNSW:mainfrom
mushrafmim:fix/117-simple-form-zombie-state-when-submission-fails

Conversation

@mushrafmim
Copy link
Contributor

Summary

When a trader submits a form and the external submission URL is unreachable or returns an error, the task previously stayed silently in INITIALIZED or DRAFT state — no indication of the failed attempt, and a blind retry could send a duplicate to the external system. This PR introduces an explicit SUBMISSION_FAILED plugin state so the failure is surfaced at the workflow level and the user can cleanly retry from the portal.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Changes Made

Backend (internal/task/plugin/simple_form.go)

  • Added SubmissionFailed plugin state constant ("SUBMISSION_FAILED")
  • Added simpleFormFSMSubmitFailed internal FSM action ("SUBMIT_FORM_FAILED")
  • Added submissionFailedErr sentinel error type — distinguishes an HTTP-level failure (where the remote system may have already recorded the data) from earlier validation failures, so only the former drives the failure transition
  • Extended NewSimpleFormFSM with 5 new edges:
    • INITIALIZED/DRAFT + SUBMIT_FORM_FAILED → SUBMISSION_FAILED [IN_PROGRESS]
    • SUBMISSION_FAILED + DRAFT_FORM → DRAFT [IN_PROGRESS]
    • SUBMISSION_FAILED + SUBMIT_FORM_COMPLETE → SUBMITTED [COMPLETED]
    • SUBMISSION_FAILED + SUBMIT_FORM_AWAIT_OGA → OGA_ACKNOWLEDGED [IN_PROGRESS]
  • Execute detects submissionFailedErr via errors.As and transitions to SUBMISSION_FAILED before returning the error response
  • submitHandler wraps the sendFormSubmission error in submissionFailedErr
  • resolveFormData returns saved local-store form data when in SUBMISSION_FAILED state so the user sees their previously submitted data on retry

Frontend (portals/apps/trader-app/src/plugins/SimpleForm.tsx)

  • Added an amber warning banner in TraderForm when pluginState === 'SUBMISSION_FAILED', prompting the user to review and resubmit

Tests (internal/task/plugin/fsm_test.go)

  • Added 7 new FSM test cases covering entry into SUBMISSION_FAILED, all three recovery paths, and two invalid transitions from that state

Testing

  • I have tested this change locally
  • I have added unit tests for new functionality
  • I have tested edge cases
  • All existing tests pass

Testing Strategy

To reproduce and verify the fix manually:

  1. Stop the NPQS server (or point the submission URL to an unreachable endpoint) so that form submission will fail.
  2. Open the trader portal, select the Edible Copra HSCode and navigate to a task that uses SimpleForm with a submission URL (e.g. the Phytosanitary Certificate form).
  3. Fill in the form and click Submit Form.
  4. The submission will fail (NPQS is down). The API will return a FORM_SUBMISSION_FAILED error.
  5. Refresh the page and navigate back to the same task.
  6. You should see the amber "Submission failed" banner at the top of the form, with the form pre-filled with your previously submitted data and the Submit button active.
  7. Restart the NPQS server and click Submit Form again — the retry should succeed and the task should progress normally.

Before this fix: Step 5 would show the form with no banner and no indication that a submission was ever attempted.

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • I have checked that there are no merge conflicts

Related Issues

Fixes #117

Additional Notes

The submissionFailedErr sentinel is intentionally package-private — it is only used within simple_form.go to signal Execute about the specific failure origin. Validation errors (schema parse, traverse, form data parse) do not use this type and therefore do not trigger the SUBMISSION_FAILED transition, leaving the task in its current state so the user can correct and resubmit without the task entering a failure state unnecessarily.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @mushrafmim, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves an issue where failed external form submissions would leave tasks in an unclear state, offering no feedback or recovery options to the user. By introducing an explicit SUBMISSION_FAILED state, the system now clearly communicates submission failures at the workflow level. This enhancement provides users with a transparent understanding of why a submission failed, allows them to review their data, and enables a clean retry mechanism directly from the portal, significantly improving the user experience and preventing potential duplicate submissions.

Highlights

  • New Plugin State: Introduced a new SUBMISSION_FAILED plugin state to explicitly indicate when an external form submission fails, preventing tasks from remaining in an ambiguous 'zombie' state.
  • Error Handling Improvement: Implemented a submissionFailedErr sentinel error type in the backend to differentiate HTTP-level submission failures from other validation errors, ensuring only relevant failures trigger the new state.
  • Finite State Machine (FSM) Enhancements: Extended the SimpleForm FSM with new transitions to and from the SUBMISSION_FAILED state, allowing for clear recovery paths such as retrying submission or drafting the form.
  • Form Data Retention: Ensured that previously submitted form data is retained and displayed to the user when a task is in the SUBMISSION_FAILED state, facilitating easier retry attempts without data loss.
  • Frontend User Feedback: Added a prominent amber warning banner in the Trader Portal to visually alert users when a form submission has failed, prompting them to review and resubmit.
  • Comprehensive Testing: Included comprehensive unit tests for the new FSM states and transitions, covering entry into SUBMISSION_FAILED and its various recovery paths, ensuring robustness.
Changelog
  • backend/internal/task/plugin/fsm_test.go
    • Added test cases for entering the SUBMISSION_FAILED state from INITIALIZED and DRAFT.
    • Added test cases for recovery paths from SUBMISSION_FAILED to DRAFT, SUBMITTED, and OGA_ACKNOWLEDGED.
    • Added test cases for invalid transitions from SUBMISSION_FAILED and to SUBMISSION_FAILED.
  • backend/internal/task/plugin/simple_form.go
    • Imported the errors package.
    • Defined simpleFormFSMSubmitFailed constant for the new action.
    • Added SubmissionFailed to the SimpleFormState constants.
    • Introduced submissionFailedErr custom error type to specifically wrap HTTP submission failures.
    • Updated NewSimpleFormFSM to include new transitions involving the SUBMISSION_FAILED state.
    • Modified the Execute function to detect submissionFailedErr and transition the plugin to SUBMISSION_FAILED.
    • Wrapped the error returned by sendFormSubmission in submitHandler with submissionFailedErr.
    • Included SubmissionFailed state in resolveFormData to ensure form data is loaded from local storage for failed submissions.
  • portals/apps/trader-app/src/plugins/SimpleForm.tsx
    • Added a conditional amber warning banner to the TraderForm component that displays when the pluginState is SUBMISSION_FAILED.
Activity
  • No specific activity (comments, reviews, or progress updates) was provided in the context.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new SUBMISSION_FAILED state to handle cases where form submission to an external service fails, preventing tasks from getting stuck in a "zombie" state. The changes include updating the backend state machine, adding logic to transition to the new state upon submission failure, and updating the frontend to display a warning banner to the user, allowing them to retry. The test suite has been extended to cover the new state and its transitions. My review identifies one area for improvement in error handling to make the fix more robust against edge cases, which has been retained as a high-severity comment.

@mushrafmim mushrafmim changed the title Fix/117 simple form zombie state when submission fails fix: simple form zombie state when submission fails Feb 26, 2026
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.

[TM/SIMPLE_FORM] Inconsistency in Simple Form Submission

2 participants