BackgroundService.stopRecorder - LateInitializationError crash#4545
BackgroundService.stopRecorder - LateInitializationError crash#4545
Conversation
…rror Check _status before accessing _service in stopRecorder and stop methods to prevent LateInitializationError when called before init() completes. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request correctly addresses a LateInitializationError crash by adding guards to the stop() and stopRecorder() methods. While this is a good step, the current implementation introduces a subtle but critical race condition. The _status variable is updated before the background service is fully configured, which could lead to other errors if these methods are called during the asynchronous initialization process. My review includes critical comments that detail this issue and propose a more robust solution to ensure the service's stability.
| if (_status == null) { | ||
| Logger.debug('BackgroundService.stop: service not initialized'); | ||
| return; | ||
| } |
There was a problem hiding this comment.
While this guard prevents the LateInitializationError, a race condition still exists. The init() method is async and sets _status to initiated before awaiting the _service.configure() call. This means stop() could be called after _service is instantiated but before it's fully configured. Calling invoke() on an unconfigured service can lead to unpredictable behavior or other errors.
To fix this properly, _status should only be set after _service.configure() has completed. This ensures that any method guarded by _status == null will only proceed when the service is fully initialized and configured.
Here is the recommended change for the init() method:
Future<void> init() async {
_service = FlutterBackgroundService();
// The status should not be set here.
await _service.configure(
// ... configurations
);
// Set status only after configuration is complete.
// Also, the redundant status assignment at the end of the original method can be removed.
_status = BackgroundServiceStatus.initiated;
}Since the init() method is not part of this PR's changes, I'm providing this feedback here. Addressing this is critical for service stability.
| if (_status == null) { | ||
| Logger.debug('BackgroundService.stopRecorder: service not initialized'); | ||
| return; | ||
| } |
There was a problem hiding this comment.
This method has the same critical race condition as the stop() method. The _status == null check is insufficient because _status is set before the service is fully configured in the async init() method. This could lead to _service.invoke() being called on an unconfigured service.
Please see my comment on the stop() method for a detailed explanation and the recommended fix in the init() method to resolve this.
Only set _status = initiated after _service.configure() finishes to prevent race condition where stop/stopRecorder could be called while the service is still being configured. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Summary
stopRecorder()andstop()methods with_statuscheck before accessing_serviceLateInitializationErrorwhen these methods are called beforeinit()completesCrash Stats
Test plan
🤖 Generated with Claude Code