fix: skip screenshot capture in batch mode - #206
Open
bobbyg603 wants to merge 1 commit into
Open
Conversation
CaptureScreenshots yielded WaitForEndOfFrame before grabbing the frame. Dedicated servers and -batchmode runs have no render loop, so that yield never resumes: the report coroutine stops there and the crash is never uploaded at all, which makes this silent data loss rather than a missing screenshot. Guard the capture with Application.isBatchMode, behind an internal Func seam so the branch is reachable from a test regardless of whether the test runner itself is batched. The seam sits next to the screenshot helper rather than with the other fields to keep this change inside the screenshot block, since two other fixes are in flight on this file. The editor variant of the same wedge (Game view not rendering) is not addressed here; detecting it needs editor-only APIs or a watchdog around the yield, which is a larger change than this fix warrants. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR prevents BugSplat exception uploads from silently wedging in Unity -batchmode / dedicated-server scenarios by skipping screenshot capture (which previously yielded WaitForEndOfFrame() and could never resume without a render loop), ensuring the upload and callback still complete.
Changes:
- Skip screenshot capture when
Application.isBatchMode(via an internalisBatchModeseam) to avoid hanging the report coroutine. - Add a runtime UnityTest to ensure posting proceeds without adding a screenshot form-data parameter when batch mode is forced on.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| Runtime/Reporter/DotNetStandardExceptionReporter.cs | Skips WaitForEndOfFrame screenshot capture in batch mode so the report upload still runs. |
| Tests/Runtime/Reporter/DotNetStandardExceptionReporterTests.cs | Adds a UnityTest covering the batch-mode + CaptureScreenshots path to ensure the post completes without screenshot form-data. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
daveplunkett
approved these changes
Aug 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #164
Problem
DotNetStandardExceptionReporter.Postyieldsnew WaitForEndOfFrame()before capturing the screenshot. On a dedicated server or any-batchmoderun there is no render loop, so that yield never resumes. The coroutine stops right there, beforeexceptionClient.Postis ever reached, so the report is never uploaded and the callback never fires. This is silent data loss, not just a missing screenshot.Fix
Skip the capture entirely when
Application.isBatchMode, and log why. Everything downstream (attachments, upload, callback) runs as normal.The check goes through an internal
Func<bool> isBatchModeseam (same pattern as the existingreportUploadGuardServiceseam) so the branch is deterministically reachable from a test whether or not the test runner itself is batched. It is declared next to the screenshot helper instead of with the other fields to keep the whole change inside the screenshot block — two other fixes (#160, #163) are in flight on this file and this keeps the three diffs disjoint.Editor variant: intentionally out of scope
The same wedge can happen in the editor when the Game view is not rendering (hidden/undocked Game view, editor test runs without a Game view). It is not addressed here, deliberately rather than by oversight:
Application.isBatchModealready covers the editor when it is launched with-batchmode(including this repo's CI test runner), so the CI path is safe.WaitForEndOfFrameagainst a frame/time budget. Both restructure the coroutine well beyond the scope of this fix, and a watchdog is the more honest general answer since it would also cover headless-graphics players.Flagging it explicitly because a hung report coroutine is silent data loss: the editor case is developer-facing and transient, whereas the batch-mode case affects shipped dedicated servers, which is why only the latter is fixed here.
Test
Post_WhenCaptureScreenshotsAndBatchMode_ShouldPostWithoutScreenshotinTests/Runtime/Reporter/DotNetStandardExceptionReporterTests.cssetsCaptureScreenshots = truewith the batch-mode seam forced true and asserts that the report still reaches the client with no screenshot form-data param. Without the fix, that test hangs onWaitForEndOfFramein any non-rendering runner instead of reaching the assertions.Verification
Compiled
Runtime/**+Tests/Runtime/**against the Unity 6000.5.6f1 managed assemblies withdotnet build: build succeeded, 0 errors, 2 pre-existing unrelatedCS0649warnings inRuntime/BugSplat.cs. The new[UnityTest]was not executed — running it requires the Unity test runner, which is not available in this environment; it will run in the Tests workflow on this PR.🤖 Generated with Claude Code