Hm, this is a multifaceted issue. Let's start at the bottom level.
wrapSyscall throws because that's how errors are reported in Swift. In general, if wrapSyscall has thrown there is no plan to recover from that error. In the case of your call stack we are attempting to work out if the socket provided to use already has a remote address, but as you're making an outbound connection it does not. We therefore suppress the error. You can expect to see at least one of these for all outbound connection attempts.
As you've correctly identified, this error is not fatal to your application because it is handled. So, why does this call throw?
Well, it throws to indicate an error. The user (in this case, a part of SwiftNIO) asked for the remote address for some reason. When an error occurs attempting to obtain it, we need to report that error. We can do it in three ways:
- Suppress the error, return
nil. This is a debugging nightmare because you lose information at the low level of the stack that cannot be recovered, so let's rule this out immediately.
- Use the standard Swift error reporting mechanism,
throw.
- Use
Result.
We currently do (2), we've ruled out (1), so to give you the usage model you want we'd have to do (3). The question is: why should we do (3)? Swift has an error propagating model: it's try/throw/catch. As this error model exists today, an affirmative argument needs to be made to not use it. I think this brings us to your other comment:
This seems to be the real crux of the issue to me, so I think it's what we should address. I think we need to clarify a few things:
- What do you want to achieve with your use of the Swift error breakpoint?
- What tool do you need to achieve that goal?
- Why did you reach for the Swift error breakpoint?
Right now my reading of your implicit argument (and I'm definitely inferring a lot here, please do correct me if I've misunderstood) is that you are essentially saying: "Libraries such as SwiftNIO should only throw an error if it will never be handled by the library". That's already quite a strong position, but as you're debugging a Vapor application I think you actually need an even stronger one, which is: "Thrown errors should never be handled by libraries, but must always propagate to the application code".
I think that's a pretty strong assertion, and I don't think I agree with it. SwiftNIO is correctly throwing an error from one part of its code, and a different part has handled the error. This is not an unreasonable design pattern, it's not an abuse of the error handling mechanism, and I think I'd be surprised to find anyone in the Swift community who thought it was an unreasonable choice.
I'm open to being convinced here, but I definitely think the onus is on you to explain why this pattern is unreasonable, and what the pattern should be instead.