Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

avoid_catches_without_on_clauses false positives #3023

Closed
Hixie opened this issue Oct 11, 2021 · 16 comments
Closed

avoid_catches_without_on_clauses false positives #3023

Hixie opened this issue Oct 11, 2021 · 16 comments
Assignees
Labels
false-positive P3 A lower priority bug or feature request set-none Does not affect any rules in a defined rule set (e.g., core, recommended, flutter) type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@Hixie
Copy link

Hixie commented Oct 11, 2021

One valid use for catching all exceptions and errors is to forward them to some error reporting logic, for example, the way that Flutter frequently catches all exceptions and forwards them to FlutterError.reportError.

It would be nice if a function like FlutterError.reportError could be annotated as a valid reason to catch exceptions, such that if the catch block contains a call to such a function, it isn't flagged with avoid_catches_without_on_clauses.

@Hixie
Copy link
Author

Hixie commented Oct 11, 2021

Forwarding to Completer.completeError would be another example of a valid reason to catch all exceptions.

@Hixie
Copy link
Author

Hixie commented Oct 11, 2021

Another example of a false positive is catch blocks that unconditionally call rethrow.

@Hixie
Copy link
Author

Hixie commented Oct 11, 2021

Another false positive is when a new exception is thrown, wrapping the original one.

@Hixie
Copy link
Author

Hixie commented Oct 11, 2021

Another false positive is when the catch block does return Future.error with the exception.

@bwilkerson
Copy link
Member

How common are the false positive cases? Would it be better to fix them all, or to just stop using it?

@Hixie
Copy link
Author

Hixie commented Oct 11, 2021

It did catch some problems, so it has value. flutter/flutter#91642 is the PR where I'm trying to turn it on (along with a few other lints), if you want to take a look.

@bwilkerson
Copy link
Member

I wonder whether there's a better way to formulate the lint (something other than "don't do this broad thing except in these 5 cases"). Maybe one or more specific use cases that should unconditionally be avoided.

@Hixie
Copy link
Author

Hixie commented Oct 12, 2021

The two problems I personally care about catching here are (1) cases where people willy-nilly swallow all exceptions because they just want to push all problems under the carpet, and (2) cases where someone wants to catch a specific exception but casts a much wider net than necessary (e.g. they just need to catch FormatException but they actually catch everything). Because Flutter is a framework it also does a lot of passing exceptions around, but I think that's pretty uncommon in apps.

@Hixie
Copy link
Author

Hixie commented Oct 12, 2021

FWIW, due to the number of false positives, we've decided in flutter/flutter#91642 to disable the lint for Flutter's framework for now, but if we can ever enable it without all the //ignores I would be very happy because it catches some insidious patterns that a lot of people (including me) accidentally use and that are very hard to fix after the fact.

Hixie added a commit to Hixie/flutter that referenced this issue Oct 14, 2021
This enables:

 - avoid_double_and_int_checks
 - avoid_js_rounded_ints
 - unsafe_html
 - use_setters_to_change_properties

It also fixes a few places where the lints were violated.

It does not enable `avoid_catches_without_on_clauses` or `avoid_catching_errors` but it does prepare us for a world where those lints have fewer false positives; see dart-lang/linter#3023 for details.
@bwilkerson bwilkerson added P3 A lower priority bug or feature request false-positive set-none Does not affect any rules in a defined rule set (e.g., core, recommended, flutter) labels Nov 7, 2022
@srawlins srawlins added the type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) label Mar 29, 2024
@srawlins
Copy link
Member

I wonder whether there's a better way to formulate the lint (something other than "don't do this broad thing except in these 5 cases"). Maybe one or more specific use cases that should unconditionally be avoided.

(2) cases where someone wants to catch a specific exception but casts a much wider net than necessary (e.g. they just need to catch FormatException but they actually catch everything).

This sounds like it would be hard to detect accurately. I think it may be hard to invert the rule's logic to target this case.

On the other hand, might not be to hard to just make some allowances for the above exceptions like:

  • If the caught error is passed to FlutterError.reportError, Completer.completeError, or Future.error, allow it.
  • If the caught error is passed as an argument to any function, whose return value is immediately thrown (i.e. the invocation is the expression in a ThrowStatement), allow it.
  • If the body of the catch has any rethrow, allow it.

@bwilkerson
Copy link
Member

... just make some allowances for the above exceptions like ...

That sounds reasonable to me.

We might also consider adding

  • If the caught error is passed as an argument to any function whose return type is Never.

@srawlins
Copy link
Member

Ooh good thought. I can add that one.

@Hixie
Copy link
Author

Hixie commented May 24, 2024

My only note would be that instead of hard-coding FlutterError.reportError, Completer.completeError, and Future.error, there be an annotation that those things have that gives them the magic ability. That way someone who develops a new framework can get the same integration with the lint.

@srawlins
Copy link
Member

It would take years to get that annotation into dart:core or a pragma annotating Completer.completeError and Future.error so I'll just hardcode them.

@srawlins srawlins self-assigned this May 26, 2024
copybara-service bot pushed a commit to dart-lang/sdk that referenced this issue May 28, 2024
Fixes dart-lang/linter#3023

This fix is a little unusually large because I have to add some
elements to both the mock flutter package, and the mock SDK. This
affects some completion tests.

Cq-Include-Trybots: luci.dart.try:flutter-analyze-try,analyzer-win-release-try,pkg-win-release-try
Change-Id: I44b68754f756cfe1cf99518957d74c4af56043f1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/368260
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
@srawlins
Copy link
Member

Fixed with dart-lang/sdk@500a8c0

@goderbauer
Copy link
Contributor

goderbauer commented Jun 17, 2024

This bug was also linked as a blocker for enabling the avoid_catching_errors lint in Flutter and when enabling it I am essentially running into the same classes of problems:

  • It flags when Errors are caught that are later rethrown after resetting some state.
  • It flags when Errors are caught to then throw a new Error with a more specific error message.
  • It flags when Errors are caught and directly passed to an error processing function (e.g. FlutterError.reportError)

I am wondering if the same lenience that was extended to avoid_catches_without_on_clauses in dart-lang/sdk@500a8c0 should also be applied to avoid_catching_errors?

FWIW, most of the uncovered reports of avoid_catching_errors are inside asserts to improve the debugging experience when those Errors happen during development. I wonder if catches in asserts should generally be exempt from the avoid_catching_errors lint or whether just those specific categories mentioned above should be exempt from the lint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
false-positive P3 A lower priority bug or feature request set-none Does not affect any rules in a defined rule set (e.g., core, recommended, flutter) type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

4 participants