-
Notifications
You must be signed in to change notification settings - Fork 593
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
Refactor Java Local Exceptions #2590
Refactor Java Local Exceptions #2590
Conversation
efecea1
to
8dedac2
Compare
3257b61
to
4a1c429
Compare
|
||
public DatagramLimitException(Throwable cause) { | ||
super(cause); | ||
this(""); |
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.
This doesn't look correct.
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 C# version has a single ctor:
public DatagramLimitException()
: base(message: "Datagram limit exceeded.", innerException: null)
{
}
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.
This doesn't look correct.
I fixed the message
The C# version has a single ctor
This is because of a difference in the UdpTransceiver.
In C#, we just use the default message:
throw new Ice.DatagramLimitException();
but in Java, we also include the packetSize in the message:
throw new com.zeroc.Ice.DatagramLimitException("message size of " + buf.size() + " exceeds the maximum packet size of " + packetSize);
In C++, we don't include this extra information:
throw DatagramLimitException(__FILE__, __LINE__);
So, Java is the odd-one-out here.
But this information seems useful to have... If you exceeded a limit, it's good to know what the limit was, right?
super(cause); | ||
public final class InvocationCanceledException extends LocalException { | ||
public InvocationCanceledException() { | ||
super("invocation canceled"); |
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.
Should be consistent with the InvocationTimeoutException message.
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.
Fixed by making it a proper sentence.
} | ||
|
||
/** This exception is raised for errors during marshaling or unmarshaling. */ | ||
public final class MarshalException extends ProtocolException { | ||
public MarshalException(String reason) { |
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 string parameter should be renamed 'message'.
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.
Good catch, fixed.
/** Base class for all Ice run-time exceptions. */ | ||
public abstract class LocalException extends Exception { | ||
/** Base class for Ice run-time exceptions. */ | ||
public class LocalException extends Exception { | ||
public LocalException() {} |
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 would remove this parameterless constructor. The caller (including derived classes) must provide a message and/or a cause.
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.
Removed. Now all constructors require a String message
.
public LocalException(String message) { | ||
super(message); | ||
} | ||
|
||
public LocalException(Throwable cause) { |
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.
Not sure we need this cause-only constructor.
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.
Also removed. Now all constructors require a String message
.
this.unknown = unknown; | ||
} | ||
|
||
public UnknownException(String unknown, Throwable cause) { | ||
super(cause); | ||
super("unknown exception with type ID '" + unknown + "'", cause); |
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.
This is bogus.
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.
Fixed, after discussing what this parameter actually holds.
public UnknownException(Throwable cause) { | ||
super(cause); | ||
this.unknown = ""; | ||
} | ||
|
||
public UnknownException(String unknown) { | ||
super("unknown exception with type ID '" + unknown + "'"); |
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.
This is bogus.
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.
Fixed, after discussing what this parameter actually holds.
super(cause); | ||
} | ||
|
||
public final class UnknownLocalException extends UnknownException { | ||
public UnknownLocalException(String unknown) { |
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.
Should be message, not unknown.
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.
Fixed, we only have a single constructor, which only takes a String message
.
super(cause); | ||
} | ||
|
||
public final class UnknownUserException extends UnknownException { | ||
public UnknownUserException(String unknown) { |
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.
Should be message, not unknown.
Also, please don't provide a 'cause' constructor.
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.
Fixed, we only have a single constructor, which only takes a String message
.
this.id = new Identity(); | ||
this.facet = ""; | ||
this.operation = ""; | ||
this(new Identity(), "", ""); |
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.
This won't produce a good message.
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.
Fixed.
/** This exception indicates a DNS problem. */ | ||
public final class DNSException extends SyscallException { | ||
public DNSException(String host) { | ||
super("Cannot resolve host '" + host + "'"); | ||
this.host = host; |
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.
We remove the host field in C#
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.
Removed in Java.
/** This exception indicates a DNS problem. */ | ||
public final class DNSException extends SyscallException { | ||
public DNSException(String host) { | ||
super("Cannot resolve host '" + host + "'"); |
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 think we can do:
super("Cannot resolve host '" + host + "'"); | |
this(host, null); |
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 surprising, but calling super(message, null)
is slightly different than super(message)
. since these constructors do different things, and the default value for cause
isn't actually null
, it's self
, which acts as a special sentinel value.
My understanding is that explicitly setting a null
cause is used to indicate that something caused it, but for some reason it's unknown. Which is not the case here.
It probably doesn't matter here... this is a niche exception, but also I find the duplication to be pretty small anyways.
super("Cannot resolve host '" + host + "'"); | ||
this.host = host; |
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.
Can't we call the other constructor here?
super("Cannot resolve host '" + host + "'"); | |
this.host = host; | |
this(host, null); |
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 surprising, but calling super(message, null)
is slightly different than super(message)
. since these constructors do different things, and the default value for cause
isn't actually null
, it's self
, which acts as a special sentinel value.
My understanding is that explicitly setting a null
cause is used to indicate that something caused it, but for some reason it's unknown. Which is not the case here.
|
||
public DatagramLimitException(Throwable cause) { | ||
super(cause); | ||
this(""); |
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 C# version has a single ctor:
public DatagramLimitException()
: base(message: "Datagram limit exceeded.", innerException: null)
{
}
public Exception(String message) { | ||
super(message); | ||
} | ||
|
||
public Exception(Throwable cause) { |
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.
Do we need this constructor?
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.
No, I deleted it.
I thought that UserException
derived from this class, but apparently it doesn't in Java (because of checked vs unchecked exceptions).
@@ -22,26 +9,11 @@ | |||
*/ | |||
public class RequestFailedException extends LocalException { | |||
public RequestFailedException() { | |||
this.id = new Identity(); |
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.
This constructor should not call the other.
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.
Yes, my bad.
Fixed.
|
||
public RequestFailedException(Identity id, String facet, String operation, Throwable cause) { | ||
super(cause); | ||
super(createMessage("RequestFailedException", id, facet, operation)); |
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 derived classes must pass the typeName, we don't want to use RequestFailedException in the message.
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.
Fixed, I forgot to add a typename
parameter to this constructor.
public UnknownException() { | ||
this.unknown = ""; | ||
} | ||
|
||
public UnknownException(Throwable cause) { |
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.
Other mappings have a single constructor with the message.
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.
Java makes frequent use of the constructor, mostly in cases where we encounter a competely unknown exception, that we know nothing else about, and just wrap in an UnknownException
.
Looking at the corresponding code in C#, we don't handle these exceptions, and just let them throw upwards.
But, some of those places have comments which suggests the Java behavior is more correct.
For example in ConnectionI
, java has an extra catch
for truly unknown exceptions:
} catch (LocalException ex) {
dispatchException(ex, requestCount);
} catch (RuntimeException | java.lang.Error ex) {
// A runtime exception or an error was thrown outside of servant code (i.e., by Ice code).
// Note that this code does NOT send a response to the client.
var uex = new UnknownException(ex);
and in C#, we just have a TODO.
catch (LocalException ex) // TODO: catch all exceptions
{
dispatchException(ex, requestCount);
}
Or in LoggerAdminLoggerI
, java has an extra else
to handle truly unknown exceptions,
if (ex instanceof com.zeroc.Ice.CommunicatorDestroyedException) {
// Expected if there are outstanding calls during communicator destruction.
} else if (ex instanceof com.zeroc.Ice.LocalException) {
_loggerAdmin.deadRemoteLogger(
p, _localLogger, (com.zeroc.Ice.LocalException) ex, "log");
} else {
_loggerAdmin.deadRemoteLogger(
p, _localLogger, new com.zeroc.Ice.UnknownException(ex), "log");
}
whereas C# looks like it just silently ignores unknown errors here:
catch (AggregateException ae)
{
if (ae.InnerException is Ice.CommunicatorDestroyedException)
{
// expected if there are outstanding calls during communicator destruction
}
if (ae.InnerException is Ice.LocalException)
{
_loggerAdmin.deadRemoteLogger(p, _localLogger,
(Ice.LocalException)ae.InnerException, "log");
}
}
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.
We should definitely remove Throwable from all UnknownException constructors and fix any code that use a UnknownException Throwable constructor.
The name Unknown is confusing but we can't change it. An UnknownException is not unknown. It's a very specific exception that means a dispatch failed with an "other" exception (other than local exception or user exception).
Whoever wrote the Java code you're showing above was unfortunately confused by the name.
We also don't want users to think "I'll throw an UnknownException that wraps some random exception - Ice likes that and will send something sensible to the client" because that's not the case.
|
||
ex.unknown = unknown; | ||
throw ex; | ||
String unknownId = is.readString(); |
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.
We read the message:
String message = ...
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.
Fixed, I had misunderstood what this unknown
field truly held.
@@ -348,6 +348,7 @@ function skipSlice(obj) | |||
catch e | |||
reason = sprintf('constructor failed for type %s with compact id %d', ... | |||
eval(sprintf('IceCompactId.TypeId_%d.typeId', compactId)), compactId); | |||
% TODO does this type still exist in MATLAB? | |||
ex = Ice.NoValueFactoryException('', reason, reason, ''); |
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.
Seems this is the only occurrence, better create a separate issue to fix it.
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.
@bernardnormier beat me to opening an issue, and already opened a PR to fix this: #2626
@@ -2581,7 +2581,7 @@ Slice::Gen::TypeScriptVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) | |||
_out << nl << " * @param communicator - The communicator for the new proxy."; | |||
_out << nl << " * @param proxyString - The string representation of the proxy."; | |||
_out << nl << " * @returns The new " << prx << " proxy."; | |||
_out << nl << " * @throws ProxyParseException - Thrown if the proxyString is not a valid proxy string."; | |||
_out << nl << " * @throws ParseException - Thrown if the proxyString is not a valid proxy string."; |
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.
ProxyParseException
was replaced with ParseException
@@ -203,7 +203,7 @@ public Reference create(string s, string propertyPrefix) | |||
end = Ice.UtilInternal.StringUtil.checkQuote(s, beg); | |||
if (end == -1) | |||
{ | |||
throw new ParseException($"mismatched quotes around value for '{option}' option in proxy string '{s}'"); | |||
throw new ParseException($"mismatched quotes around value for {option} option in proxy string '{s}'"); |
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.
Everywhere else in this file, we don't put quotes around the {option}
(ex: -c, -t, -h, ...)
@@ -233,12 +233,12 @@ protected override bool checkOption(string option, string argument, string endpo | |||
_timeout = int.Parse(argument, CultureInfo.InvariantCulture); | |||
if (_timeout < 1) | |||
{ | |||
throw new ParseException($"invalid timeout value '{argument}' in endpoint {endpoint}"); | |||
throw new ParseException($"invalid timeout value '{argument}' in endpoint '{endpoint}'"); |
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.
In every other place in this PR, we always wrapped the {endpoint}
in single quotes
@@ -337,7 +337,7 @@ protected override bool checkOption(string option, string argument, string endpo | |||
{ | |||
if (argument == null) | |||
{ | |||
throw new ParseException($"unexpected argument '{argument}' provided for {option} option in endpoint '{endpoint}'"); | |||
throw new ParseException($"no argument provided for {option} option in endpoint '{endpoint}'"); |
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.
Looked like an over-zealous copy/paste.
This is what the message used to be, and continues to be in other place we test for a null argument.
Also it's kind of weird to check argument == null
, then try to print it...
@@ -1441,7 +1441,7 @@ private List<EndpointI> parseEndpoints(string endpts, bool oaEndpoints) | |||
EndpointI endp = _instance.endpointFactoryManager().create(s, oaEndpoints); | |||
if (endp is null) | |||
{ | |||
throw new ParseException($"invalid object adapter endpoint {s}'"); | |||
throw new ParseException($"invalid object adapter endpoint '{s}'"); |
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.
mismatched single quotes.
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.
Sounds like this should also be a full sentence, but I'm going to leave it alone for now.
@@ -22,26 +9,11 @@ | |||
*/ | |||
public class RequestFailedException extends LocalException { | |||
public RequestFailedException() { | |||
this.id = new Identity(); |
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.
Yes, my bad.
Fixed.
|
||
public RequestFailedException(Identity id, String facet, String operation, Throwable cause) { | ||
super(cause); | ||
super(createMessage("RequestFailedException", id, facet, operation)); |
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.
Fixed, I forgot to add a typename
parameter to this constructor.
public UnknownException() { | ||
this.unknown = ""; | ||
} | ||
|
||
public UnknownException(Throwable cause) { |
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.
Java makes frequent use of the constructor, mostly in cases where we encounter a competely unknown exception, that we know nothing else about, and just wrap in an UnknownException
.
Looking at the corresponding code in C#, we don't handle these exceptions, and just let them throw upwards.
But, some of those places have comments which suggests the Java behavior is more correct.
For example in ConnectionI
, java has an extra catch
for truly unknown exceptions:
} catch (LocalException ex) {
dispatchException(ex, requestCount);
} catch (RuntimeException | java.lang.Error ex) {
// A runtime exception or an error was thrown outside of servant code (i.e., by Ice code).
// Note that this code does NOT send a response to the client.
var uex = new UnknownException(ex);
and in C#, we just have a TODO.
catch (LocalException ex) // TODO: catch all exceptions
{
dispatchException(ex, requestCount);
}
Or in LoggerAdminLoggerI
, java has an extra else
to handle truly unknown exceptions,
if (ex instanceof com.zeroc.Ice.CommunicatorDestroyedException) {
// Expected if there are outstanding calls during communicator destruction.
} else if (ex instanceof com.zeroc.Ice.LocalException) {
_loggerAdmin.deadRemoteLogger(
p, _localLogger, (com.zeroc.Ice.LocalException) ex, "log");
} else {
_loggerAdmin.deadRemoteLogger(
p, _localLogger, new com.zeroc.Ice.UnknownException(ex), "log");
}
whereas C# looks like it just silently ignores unknown errors here:
catch (AggregateException ae)
{
if (ae.InnerException is Ice.CommunicatorDestroyedException)
{
// expected if there are outstanding calls during communicator destruction
}
if (ae.InnerException is Ice.LocalException)
{
_loggerAdmin.deadRemoteLogger(p, _localLogger,
(Ice.LocalException)ae.InnerException, "log");
}
}
|
||
ex.unknown = unknown; | ||
throw ex; | ||
String unknownId = is.readString(); |
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.
Fixed, I had misunderstood what this unknown
field truly held.
@@ -348,6 +348,7 @@ function skipSlice(obj) | |||
catch e | |||
reason = sprintf('constructor failed for type %s with compact id %d', ... | |||
eval(sprintf('IceCompactId.TypeId_%d.typeId', compactId)), compactId); | |||
% TODO does this type still exist in MATLAB? | |||
ex = Ice.NoValueFactoryException('', reason, reason, ''); |
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.
@bernardnormier beat me to opening an issue, and already opened a PR to fix this: #2626
public UnknownException() { | ||
this.unknown = ""; | ||
} | ||
|
||
public UnknownException(Throwable cause) { |
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.
We should definitely remove Throwable from all UnknownException constructors and fix any code that use a UnknownException Throwable constructor.
The name Unknown is confusing but we can't change it. An UnknownException is not unknown. It's a very specific exception that means a dispatch failed with an "other" exception (other than local exception or user exception).
Whoever wrote the Java code you're showing above was unfortunately confused by the name.
We also don't want users to think "I'll throw an UnknownException that wraps some random exception - Ice likes that and will send something sensible to the client" because that's not the case.
* exceptions declared in the <code>throws</code> clause can be raised. | ||
* The dispatch returned a {@link UserException} that was not declared in the operation's exception | ||
* specification (the <code>throws</code> clause). This is necessary in order to not violate the | ||
* contract established by an operation's signature: Only local exceptions and user 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.
This doc comment is bogus.
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.
Why? Do we allow arbitrary user exceptions to be thrown now?
|
||
public UnknownUserException(String unknown, Throwable cause) { | ||
super(unknown, cause); | ||
public UnknownUserException(String message, Throwable cause) { |
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.
Please no Throwable.
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 removed this.
In Java, we used to store the actual UserException
in this field, so we could put it's stack trace in the expectedDetails
.
Removing this does means that the details will be less... detailed now.
cpp/src/Ice/Initialize.cpp
Outdated
@@ -179,7 +179,7 @@ Ice::ThreadHookPlugin::ThreadHookPlugin( | |||
{ | |||
if (communicator == nullptr) | |||
{ | |||
throw PluginInitializationException(__FILE__, __LINE__, "Communicator cannot be null"); | |||
throw PluginInitializationException(__FILE__, __LINE__, "Communicator cannot be null."); |
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.
Yes, please revert.
In C++, the style we adopted is lowercase and no period. It should actually be communicator
here.
I'm just trying to keep all the error messages consistent across languages.
We don't want to do that. The goal is for error messages in language X to be consistent with error message in language X. Not adopt our own cross-language Ice style.
cpp/src/Ice/ObjectAdapterI.cpp
Outdated
@@ -934,7 +934,7 @@ Ice::ObjectAdapterI::initialize(optional<RouterPrx> router) | |||
// | |||
if (router == nullopt && noProps) | |||
{ | |||
throw InitializationException(__FILE__, __LINE__, "object adapter `" + _name + "' requires configuration"); | |||
throw InitializationException(__FILE__, __LINE__, "Object adapter `" + _name + "' requires configuration."); |
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.
Please revert all these updates.
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.
Alright, now that I have a bearing for what the intent is, I'll revert/fix my changes as necessary.
Unfortunately, we're very inconsistent about which message style we use across our languages, so extrapolated the wrong idea.
One day we should consider a cleanup pass to fix all these messages...
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 fixed all my changes to the messages, not by reverting them, but by changing them to be correct in each language.
Since most of them didn't follow the guidelines you laid out...
csharp/src/Ice/ConnectionI.cs
Outdated
@@ -171,7 +171,7 @@ public void close(ConnectionClose mode) | |||
setState( | |||
StateClosing, | |||
new ConnectionClosedException( | |||
"The connection was closed gracefully by the application.", | |||
"Connection closed gracefully by the application.", |
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 preferred style in C# is a full sentence. So I would keep "Ther connection was ..." and fix the message below.
csharp/src/Ice/PluginManagerI.cs
Outdated
@@ -44,7 +44,7 @@ public void initializePlugins() | |||
{ | |||
if (_initialized) | |||
{ | |||
throw new InitializationException("Plug-ins already initialized."); | |||
throw new InitializationException("plug-ins already initialized"); |
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.
We should follow each programming language best practices. In C#, it's full sentences, starting with a capital letter and ending with a period. Please revert this update.
@@ -256,15 +254,15 @@ private OutgoingResponse createOutgoingResponseCore(Throwable exc) { | |||
} else if (exc instanceof UnknownLocalException ex) { | |||
exceptionId = ex.ice_id(); | |||
replyStatus = ReplyStatus.UnknownLocalException; | |||
unknownExceptionMessage = ex.unknown; | |||
unknownExceptionMessage = ex.toString(); |
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.
This is not correct. The message of an UnknownXxxException is returned by getMessage, not toString.
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.
Also fixed.
@@ -285,13 +283,17 @@ private OutgoingResponse createOutgoingResponseCore(Throwable exc) { | |||
|| replyStatus == ReplyStatus.UnknownException)) { | |||
ostr.writeByte(replyStatus.value()); | |||
if (unknownExceptionMessage == null) { | |||
unknownExceptionMessage = "Dispatch failed with " + exceptionId + ": " + exc.getMessage(); | |||
unknownExceptionMessage = "Dispatch failed with " + exc.toString(); |
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.
That's correct.
if (rfe.id.name.isEmpty()) { | ||
rfe.id = id; | ||
rfe.facet = facet; | ||
Identity id = rfe.id; |
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 find defining local variables that hide fields pretty confusing and unexpected, especially in a big method like this one.
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'm open to changing it, but this is what we're doing in every language, so I'd like to change it in all of them.
See #2345
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.
In other languages, this code is not in Current, but in a separate class. So id/facet/operation don't hide fields.
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.
Fair enough, I added a prefix in Java to disambiguate them.
@@ -5,7 +5,7 @@ | |||
/** This exception indicates socket errors. */ | |||
public class SocketException extends SyscallException { | |||
public SocketException() { | |||
super(); | |||
super((String) null); |
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.
What is the difference between super()
and super((String)null)
?
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 parameterless constructor was removed from SyscallException
, and Java doesn't support default parameters, so here we explicitly pass null
to say that we don't have any useful message.
But SyscallException
has 2 constructors which only take 1 parameter:
SyscallException(Throwable cause)
and SyscallException(String message)
so passing null
is ambiguous, so we have to do this awkward looking cast to let the compiler know which constructor we want to call.
I removed it from |
if (rfe.operation.isEmpty()) { | ||
rfe.operation = operation; | ||
} | ||
String operation = rfe.operation.isEmpty() ? this.operation : rfe.operation; |
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.
operation also shadows a field
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.
Fixed.
This PR finishes our refactoring of local exceptions by doing it in Java.
For a list of which exceptions changed to what, see this table from the original PR.
Along the way, I cross-checked my changes with the other languages.
While doing so, I noticed some bugs, inconsistencies, typos, etc. that seemed small and related enough to just fix in this PR.