Skip to content

Fix: Stop reporting network errors as crashes#4432

Open
aaravgarg wants to merge 1 commit intomainfrom
fix/skip-network-error-crash-reports
Open

Fix: Stop reporting network errors as crashes#4432
aaravgarg wants to merge 1 commit intomainfrom
fix/skip-network-error-crash-reports

Conversation

@aaravgarg
Copy link
Collaborator

Summary

  • Network connectivity issues (DNS failures, timeouts, connection errors) were being reported as fatal crashes
  • This caused misleading crash reports when users simply went offline
  • Added _isNetworkError() helper to detect expected network failures and skip crash reporting for them
  • The app already handles null responses gracefully, so behavior is unchanged

Test plan

  • Verify app still works normally when online
  • Turn on airplane mode and verify no new crash reports are generated for network errors
  • Check that actual non-network errors are still reported to crash reporter

🤖 Generated with Claude Code

Network connectivity issues (DNS failures, timeouts, connection errors)
are expected when users go offline. These were being reported as fatal
crashes, causing misleading crash reports.

Added _isNetworkError() helper to detect expected network failures and
skip crash reporting for them. The app already handles null responses
gracefully.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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 correctly prevents network-related errors from being reported as crashes by introducing a _isNetworkError helper function. The implementation is sound and applied across all relevant API call methods. My review includes suggestions to improve code readability and reduce duplication by extracting common logic into helper functions, aligning with the principle of preferring helper functions over inlined logic (Rule 4), which will enhance long-term maintainability.

Comment on lines +21 to +29
final message = error.message.toLowerCase();
return message.contains('socketexception') ||
message.contains('failed host lookup') ||
message.contains('connection refused') ||
message.contains('connection reset') ||
message.contains('connection closed') ||
message.contains('network is unreachable') ||
message.contains('no route to host') ||
message.contains('nodename nor servname provided');
Copy link
Contributor

Choose a reason for hiding this comment

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

high

This long chain of || conditions can be hard to read and maintain. You can improve readability by using a Set of error messages and the any() method.

    final message = error.message.toLowerCase();
    const networkErrorMessages = {
      'socketexception',
      'failed host lookup',
      'connection refused',
      'connection reset',
      'connection closed',
      'network is unreachable',
      'no route to host',
      'nodename nor servname provided',
    };
    return networkErrorMessages.any(message.contains);

Comment on lines 160 to 168
} catch (e, stackTrace) {
Logger.debug('HTTP request failed: $e, $stackTrace');
PlatformManager.instance.crashReporter.reportCrash(e, stackTrace, userAttributes: {'url': url, 'method': method});
Logger.debug('HTTP request failed: $e');
// Only report non-network errors to crash reporter.
// Network errors (offline, DNS failure, timeouts) are expected and not bugs.
if (!_isNetworkError(e)) {
PlatformManager.instance.crashReporter.reportCrash(e, stackTrace, userAttributes: {'url': url, 'method': method});
}
return null;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The error handling logic, specifically checking _isNetworkError before reporting a crash, is duplicated across four methods (makeApiCall, makeMultipartApiCall, makeStreamingApiCall, makeMultipartStreamingApiCall). This duplication can lead to maintenance issues. To improve this, you can extract this logic into a dedicated helper function.

For example, you could add a new private function in this file:

void _reportErrorIfNotNetwork(Object e, StackTrace stackTrace, {required String url, required String method}) {
  if (!_isNetworkError(e)) {
    PlatformManager.instance.crashReporter.reportCrash(e, stackTrace, userAttributes: {'url': url, 'method': method});
  }
}

Then, you can call this function from each catch block, which will make the code cleaner and easier to maintain. For example, this block would become:

} catch (e, stackTrace) {
    Logger.debug('HTTP request failed: $e');
    _reportErrorIfNotNetwork(e, stackTrace, url: url, method: method);
    return null;
}
References
  1. Prefer using existing helper functions over inlining their logic, especially when they handle complex cases like fallbacks or error handling. Inlining can introduce subtle bugs by missing parts of the original logic. This comment suggests creating a new helper function to avoid duplicating error handling logic, which aligns with the principle of this rule.

@aaravgarg aaravgarg requested a review from mdmohsin7 January 28, 2026 16:33
@aaravgarg
Copy link
Collaborator Author

@mdmohsin7 bump

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