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

Add withErrorReporting #143

Merged
merged 7 commits into from
Jan 29, 2025
Merged

Add withErrorReporting #143

merged 7 commits into from
Jan 29, 2025

Conversation

stephencelis
Copy link
Member

It's common to write the following boilerplate when working with code that can throw errors:

do {
  try work()
} catch {
  reportIssue(error)
}

Let's extract this pattern to a helper that can save at least some boilerplate:

withErrorReporting {
  try work()
}

Or even make it a 1-liner in some cases:

withErrorReporting(catching: work)

It's common to write the following boilerplate when working with code
that can throw errors:

```swift
do {
  try work()
} catch {
  reportIssue(error)
}
```

Let's extract this pattern to a helper that can save at least some
boilerplate:

```swift
withErrorReporting {
  try work()
}
```

Or even make it a 1-liner in some cases:

```swift
withErrorReporting(catching: work)
```
@stephencelis stephencelis merged commit adadb00 into main Jan 29, 2025
15 checks passed
@stephencelis stephencelis deleted the with-error-reporting branch January 29, 2025 22:21
@lukeredpath
Copy link

Would you be willing to accepted a PR that adds an overload of this helper that rethrows rather than returns an optional? This can be helpful in situations where you are using async let, e.g.:

async let first = withErrorReporting("First") { try await first() }
async let second = withErrorReporting("Second") { try await second() }

If you want the overall function to still rethrow, having withErrorReporting swallow the error isn't that helpful.

@stephencelis
Copy link
Member Author

@lukeredpath As long as there aren't overload issues that sounds like a good idea to us!

@lukeredpath
Copy link

lukeredpath commented Feb 6, 2025

I've been trying this out locally in my project and unfortunately using the same function name does seem to cause some overload issues. I'm not sure if its possible to resolve it, for now I've been using my own helper with a different name:

public func withRethrowingErrorReporting<R>(
    _ message: @autoclosure () -> String? = nil,
    to reporters: [any IssueReporter]? = nil,
    fileID: StaticString = #fileID,
    filePath: StaticString = #filePath,
    line: UInt = #line,
    column: UInt = #column,
    catching body: () async throws -> sending R
) async rethrows -> R {
    func performOperation() async throws -> R {
        do {
            return try await body()
        } catch {
            reportIssue(error, message(), fileID: fileID, filePath: filePath, line: line, column: column)
            throw error
        }
    }
    if let reporters {
        return try await withIssueReporters(reporters) {
            try await performOperation()
        }
    } else {
        return try await performOperation()
    }
}

I wonder, if this was part of the library, the versions that do not throw could be marked as @_disfavoredOverload.

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.

3 participants