Add isSubmitting flags to prevent multiple submissions#901
Add isSubmitting flags to prevent multiple submissions#901PythonSmall-Q wants to merge 13 commits intodevfrom
Conversation
Signed-off-by: Shan Wenxiao <seanoj_noreply@yeah.net>
There was a problem hiding this comment.
Pull request overview
This PR adds “isSubmitting” guard flags in several click handlers to prevent duplicate submissions across the script’s submission and BBS posting/reply flows.
Changes:
- Add
isSubmittinggating for the problem submission button to ignore repeated clicks while a submission is in progress. - Add
isSubmittingPostgating for creating new discussion posts. - Add
isSubmittingReplygating for posting replies in a thread.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Submit.disabled = false; | ||
| Submit.value = "提交"; | ||
| isSubmitting = false; | ||
| } |
There was a problem hiding this comment.
isSubmitting is only reset in the non-redirect branch of the PassCheck fetch(...).then(...) chain. If the fetch rejects (network error/timeout) or an exception occurs before reaching this branch, Submit can remain disabled and isSubmitting stays true, preventing retry. Add explicit error handling (e.g., .catch(...) or try/catch/finally) in the PassCheck submission flow to restore UI state and clear the flag.
| } | |
| } | |
| }).catch((error) => { | |
| if (UtilityEnabled("DebugMode")) { | |
| console.error("Submission request failed:", error); | |
| } | |
| ErrorElement.style.display = "block"; | |
| ErrorMessage.style.color = "red"; | |
| ErrorMessage.innerText = "提交失败!请检查网络后重试!"; | |
| }).finally(() => { | |
| Submit.disabled = false; | |
| Submit.value = "提交"; | |
| isSubmitting = false; |
| let isSubmittingPost = false; | ||
| SubmitElement.addEventListener("click", async () => { | ||
| if (isSubmittingPost) { | ||
| return; | ||
| } | ||
| isSubmittingPost = true; | ||
| ErrorElement.style.display = "none"; |
There was a problem hiding this comment.
isSubmittingPost is set to true before calling RequestAPI(...), but it’s only reset inside the success callback. Since RequestAPI currently only registers onload (no onerror/ontimeout) and JSON parse errors can also prevent the callback from running, a failed request can leave isSubmittingPost stuck true (and the UI disabled) until a page reload. Ensure RequestAPI invokes a failure path (onerror/ontimeout/parse failure) and/or reset the flag in a guaranteed finally-style path.
| let isSubmittingReply = false; | ||
| SubmitElement.addEventListener("click", async () => { | ||
| if (isSubmittingReply) { | ||
| return; | ||
| } | ||
| isSubmittingReply = true; | ||
| ErrorElement.style.display = "none"; | ||
| SubmitElement.disabled = true; | ||
| SubmitElement.children[0].style.display = "inline-block"; |
There was a problem hiding this comment.
isSubmittingReply is set to true before RequestAPI("NewReply", ...), but it’s only cleared in the callback. If the request errors/ times out, or if RequestAPI fails to parse/dispatch the callback, the flag can remain true (and combined with disabled can prevent retries without a reload). Add a guaranteed reset path by handling onerror/ontimeout in RequestAPI and/or clearing the flag in an always-run cleanup path.
| ErrorMessage.innerText = "编译错误:\n" + Response.stderr.trim(); | ||
| document.querySelector("#Submit").disabled = false; | ||
| document.querySelector("#Submit").value = "提交"; | ||
| isSubmitting = false; | ||
| return false; | ||
| } else { | ||
| PassCheck.click(); |
There was a problem hiding this comment.
In the CompileError check flow, JSON.parse(ResponseData.responseText) is not guarded. If cppinsights returns a non-JSON error page or an empty response, this throws and the handler exits without re-enabling the Submit button or clearing isSubmitting, effectively locking submissions until reload. Wrap the parse in try/catch and ensure UI + isSubmitting are reset on parse/network errors.
| Submit.disabled = false; | ||
| Submit.value = "提交"; | ||
| isSubmitting = false; | ||
| } | ||
| }) | ||
| }); | ||
|
|
||
| let isSubmitting = false; | ||
| Submit.addEventListener("click", async () => { |
There was a problem hiding this comment.
isSubmitting is assigned in the PassCheck handler before its let isSubmitting = false; declaration later in the same scope. While it will usually work due to event timing, it’s confusing and easy to break (e.g., if the handler ever runs earlier) and can trigger TDZ issues if refactored. Declare isSubmitting before adding the PassCheck listener (or otherwise ensure the variable is declared above all uses).
|
@PythonSmall-Q I've opened a new pull request, #902, to work on those changes. Once the pull request is ready, I'll request review from you. |
Summary by cubic
Add isSubmitting guards to block duplicate submissions for code, new posts, and replies. Bumped to v2.7.3 (prerelease) and updated Update.json with the 2.7.3 entry (timestamp + description).
Written for commit c20cd77. Summary will update on new commits.