Rule request: [discarded_async_let_error] async let discards thrown errors
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 19.7k
- Forks
- 2.3k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 11
Description
New Issue Checklist
- Updated SwiftLint to the latest version
- I searched for existing GitHub issues
New rule request
When using async let on a throwing function, with or without try, or, inside or outside of a do/catch, the thrown error is discarded and this might be unexpected.
Wrapping in a do { } catch { } adds a false sense of effectiveness. Maybe there should be a unneeded_do_catch rule, too.
Either the do/catch should be removed or the async let _ = try ... should be replaced with try await ... while avoiding try?.
try? converts a thrown error to an optional and still discards the error.
try! avoids the described problem with other risks.
-
Why should this rule be added? Share links to existing discussion about what
the community thinks about this.
This helps simplify and correct code because either the do/catch was written and is not needed or the programmer has made a logical mistake by discarding the error by forgetting totry awaitthe result. Or, the programmer should usetry awaitinstead ofasync let. I'm not sure what the community thinks. -
Examples:
do {
async let resultOne = MyThrowingFunction() // Trigger
async let resultTwo = try MyThrowingFunction() // Trigger
// async let resultThree = try? MyThrowingFunction() // Potential trigger
} catch {
print("This never gets printed for any of the above")
}
Task {
async let resultOne = MyThrowingFunction() // Trigger
async let resultTwo = try MyThrowingFunction() // Trigger
// async let resultThree = try? MyThrowingFunction() // Potential trigger
}
do {
async let resultOne = MyThrowingFunction() // Won't trigger because do/catch + await
try await resultOne
} catch {
print("This gets printed")
}
do {
async let resultTwo = try MyThrowingFunction() // Won't trigger because do/catch + await
try await resultTwo
} catch {
print("This gets printed")
}
do {
async let resultTwo = try MyThrowingFunction() // Probably should trigger since try? await still discards the error
try? await resultTwo
} catch {
print("This gets printed")
}
Task {
async let resultOne = MyThrowingFunction() // Trigger
async let resultTwo = try MyThrowingFunction() // Trigger because no do/catch even though it is awaited.
async let resultThree = try? MyThrowingFunction() // Trigger
try await resultTwo
}
-
Should the rule be configurable, if so what parameters should be configurable?
Configurations could include checkingtry?and/ortry!. -
Should the rule be opt-in or enabled by default? Why?
Enabled by default because it catches potential logical errors by the programmer and should not have many occurrences.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The issue names no implementation files, entry points, or tests. Start by reviewing the async let examples and deciding the intended handling of discarded errors, try?, try!, and do/catch cases. Done means the rule's scope and default or configuration behavior are agreed and the listed trigger and non-trigger cases are covered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100