-
Notifications
You must be signed in to change notification settings - Fork 10.6k
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
C#: misuse of InvalidOperationException on network error #7223
Comments
+1 to both points. I was left scratching my head as well and it didn't occur to me to dig into logging just to find out the why of Send failed. I just assumed I was doing something wrong (just starting out with grpc here).
|
@kkm000, thanks for filing this issue, I fully agree with your thoughts. Seems like this is something we need to fix. Also, I apologize for not reacting sooner, I was out of office for extended period of time. Here are my thoughts on what needs to be done and how. I will start with the client side calls
Does that make sense? If so, things seem to be fairly clear on the client side. On the server side, things works similarly with the biggest difference being that we cannot throw and RpcException (that comes with a status code) simply because server side calls don't have a status code associated with them - if they fail, they finish with a binary success/non-success flag reported back to the server code. So on the server side, we need to figure out which exception type is the most fitting here - my personal favorite seems to be IOException (but do be honest I am not 100% convinced I like that choice either). What is your opinion on what the server side behavior should be (and what exception type to use)? |
Would it be worth it to try and do this in a non-breaking way, or at least less breaking? Possibly sub-classing the current InvalidOperationException? (got rid of one idea like that in #7861). |
So what server-side failure type are we talking about? Something like "client killed connection"? |
@jskeet yes, if something went wrong with the call and we weren't able to finish the call normally (by sending client a status). That could be network error, client died, etc. |
Sounds like |
Another option would be to throw parameterless "RpcException" for more consistency with client side (but it's just an idea). |
I like the idea of throwing an
|
Actually See #8084 for the PR with the fix. |
Sounds great. So looking briefly at #8084, we now throw an |
@imiuka Yes, exactly (once we merge and release of course). |
#8084 has been been merged. |
Consider
(the
.Wait()
here is abused for demo purposes only)If
machine
is not listening, them theWriteAsync
call will throwInvalidOperationException
with the messageSend failed
. There is a huge problem with that.[TL;DR: gRPC is using a wrong exception class].
InvalidOperationException
semantics is quite close to that of C++ASSERT
; it says, essentially, "you are doing something wrong." There is no explicit guideline published by MS as far as I know (and, unlike Win32, I cannot commend .NET docs on exhaustiveness), but the documentation opposes the IOE to theArgumentException
. Other development community guidelines (a good example) talk aboutNotSupportedException
as opposed toNotImplementedException
, and there is also of courseObjectDisposedException
. What is common among these presumed opposites is that all of them tell the programmer that the code is not using the object correctly. Kind of what theASSERT
does.Now this is clearly not our case. I the programmer cannot control the state of network!
InvalidOperationException
is out of place here. I cannot think of a good predefined class for an exception in this case. For one,RpcException
with theUnavailable
status would certainly not be out of place here (and I think the previous gRPC did do just that, in v0.11).[TL;DR: gRPC is throwing out information about error condition]. Consider
I almost hear you saying ugh! as in ugly. Unfortunately, the exception message is the only additional piece of information that I have here. And, the scariest thing, this is how my production code currently looks. Now, using another exception type would be a great help to avoid this ugliness. I am talking only an enhancement here, so this is a lesser point. In the debug log there is (with long paths snipped for clarity):
Would not I love to have access to this information through exception properties! Even in a form of loosely defined key/value pairs. I can make decisions like whether I should complain about invalid configuration, or keep calm and retain the address in the load balancer list to retry later.
The text was updated successfully, but these errors were encountered: