-
Notifications
You must be signed in to change notification settings - Fork 190
Adjust parent types for exceptions #1924
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
Conversation
Motivation: After revisiting all existing exception types, we found that some of them use incorrect parent type. Modifications: - Use more appropriate parent type for existing exceptions; - Regenerate `serialVersionUID` for updated exception classes; - Fix how the message is generated for `MessageEncodingException`; - Change exception type thrown by `DefaultMultiAddressUrlHttpClientBuilder` to `MalformedURLException` when request target is not in absolute-form; - Remove unused ctor from `ResponseTimeoutTest`; - Use `StacklessConnectionRejectedException` for `RoundRobinLoadBalancer`; Result: Exceptions have more appropriate parent types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't expect it to be an impactful breaking change because most of the users use our types instead of parent types. Should be an appropriate change for 0.42 release, wdyt?
/** | ||
* Thrown when a newly created connection was rejected. | ||
*/ | ||
public final class ConnectionRejectedException extends RuntimeException implements RetryableException { | ||
private static final long serialVersionUID = -2573006397795678870L; | ||
public class ConnectionRejectedException extends SocketException implements RetryableException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debated between ConnectException
and SocketException
. Based on their javadoc, decided to go with SocketException
because technically the connection was already established, but there was a problem "accessing" it due to a selector or a host becoming unavailable.
@@ -40,8 +40,8 @@ | |||
/** | |||
* An {@link Exception} instance used to indicate termination of repeats. | |||
*/ | |||
public static final class TerminateRepeatException extends Exception { | |||
private static final long serialVersionUID = -1725458427890873886L; | |||
public static final class TerminateRepeatException extends RuntimeException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The decision to throw this exception happens at runtime
*/ | ||
@Deprecated | ||
public final class MessageEncodingException extends RuntimeException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ProtoBufSerializationProviderBuilder
was deprecated only in the main branch, we don't need to cherry-pick this into 0.41
...rotobuf/src/main/java/io/servicetalk/grpc/protobuf/ProtoBufSerializationProviderBuilder.java
Outdated
Show resolved
Hide resolved
import javax.annotation.Nullable; | ||
|
||
final class UnsupportedHttpChunkException extends SerializationException { | ||
final class UnsupportedHttpChunkException extends IllegalArgumentException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change from IllegalArgumentException
to SerializationException
was made only in the main branch in #1673. This is not related to serialization and more about what payload body object users passed to an HTTP message. Reverting back to IllegalArgumentException
.
cc @Scottmitch
return defer(() -> { | ||
try { | ||
return selectClient(request).request(strategy, request).subscribeShareContext(); | ||
} catch (Throwable t) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The try-catch
here is necessary anyway, because methods that return async sources are not expected to throw.
/** | ||
* Thrown when no host is available but at least one is required. | ||
*/ | ||
public class NoAvailableHostException extends RuntimeException implements RetryableException { | ||
private static final long serialVersionUID = 5340791072245425967L; | ||
public class NoAvailableHostException extends SocketException implements RetryableException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it a "SocketException"? I would rather keep it a runtime one or associate with a LB/SD parent type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The intend was to make it IOException
because it prevents a request execution due to unavailability to execute an IO operation. During offline discussion, @bondolo recommended a more specific subtype - SocketException
. I'm agreed with that proposal because it notifies that there are no sockets available at this point of time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't see a reason to block the change but I don't agree that this is a good correlation. I agree that IOException
is a valid super type, but SocketException
is clearly doc'ed to do with failure to access or create a socket. In our case this is not even related to a connection but rather to host-finding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I was reading "failure to access a socket" as "no hosts -> no access" 😄
Changing to IOException
: c2b41cf
@@ -63,6 +64,9 @@ | |||
* A builder of {@link StreamingHttpClient} instances which have a capacity to call any server based on the parsed | |||
* absolute-form URL address information from each {@link StreamingHttpRequest}. | |||
* <p> | |||
* If {@link HttpRequestMetaData#requestTarget()} is not an absolute-form URL, a {@link MalformedURLException} will be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly just a personal preference but I usually prefer URISyntaxException
to MalformedURLException
because the later often gets handled as a generic IOException
by lazy people who hate checked exceptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm... Haven't thought about URISyntaxException
. Reading its javadoc, it's hard to say that /path
is expected to trigger URISyntaxException
. Description of MalformedURLException
is better aligned with multi-address client requirements. What others think?
I'm agreed that users usually catch broad IOException
. A good thing with Reactive Streams is that you don't have to throw and try-catch checked exceptions, everything is propagated through onError
as Throwable
.
BlockingHttpClient
signature defines a request method as throws Exception
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've opened a separate PR #1955 for this change to make it move visible in release notes
Motivation:
After revisiting all existing exception types, we found that some of
them use incorrect parent type.
Modifications:
ConnectionRejectedException
extendRuntimeException
->SocketException
;NoAvailableHostException
extendRuntimeException
->IOException
;DuplicateAttributeException
extendRuntimeException
->IllegalStateException
;TerminateRepeatException
extendException
->RuntimeException
;ClosedServiceDiscovererException
extendRuntimeException
->ClosedChannelException
;UnsupportedHttpChunkException
extendSerializationException
->IllegalArgumentException
;serialVersionUID
for updated exception classes;StacklessConnectionRejectedException
forRoundRobinLoadBalancer
;MessageEncodingException
as@Deprecated
(was missed during rework ofserialization API);
ResponseTimeoutTest
;Result:
Exceptions have more appropriate parent types.