-
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 JavaScript local exceptions #2574
Conversation
@@ -2,87 +2,12 @@ | |||
// Copyright (c) ZeroC, Inc. All rights reserved. | |||
// | |||
|
|||
const toString = function (key, object, objectTable, ident) { |
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 was used to override the standard toString method and print all attributes. It seems overcomplicated and of little use.
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 not a concern for local exceptions, since they must all provide a message. But it could be a concern for user exceptions that never provide any message.
When you print (toString) a user exception, what do you get? Only the type ID?
In C++ and C#, we give users the ability to define a custom "toString" for their user exceptions. How does this work in JS?
Note that constructing a user exception with a message string is not a good solution: user exceptions are often unmarshaled and the unmarshaling code doesn't have a message string to provide.
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 JS you can patch the class prototype to override a method. This would allow users to provide their own toString
return s; | ||
} | ||
|
||
static captureStackTrace(object) { |
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 don't need this. The stack property is already part of the base Error
class.
* | ||
* @return The string representation of the object identity. | ||
**/ | ||
export function identityToString(ident, toStringMode = ToStringMode.Unicode) { |
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.
Move to a separate file to avoid circular dependencies with LocalExceptions.js
// s.push("\nfacet = "); | ||
// if (facet.length > 0) { | ||
// s.push(StringUtil.escapeString(facet[0], "", toStringMode)); | ||
// } |
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 code was broken, and when trying to fix it I noticed this introduces a circular dependency. I will fix it in a separate PR.
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.
Looks good.
js/src/Ice/ExUtil.js
Outdated
|
||
export function throwUOE(expectedType, v) { | ||
// If the object is an unknown sliced object, we didn't find an value factory. |
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.
a value factory
js/src/Ice/ExUtil.js
Outdated
"expected element of type `" + expectedType + "' but received `" + type + "'", | ||
type, | ||
expectedType, | ||
let expected = expectedType.ice_staticId(); // TODO add ice_staticId |
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.
expectedType should be a type ID to start with.
js/test/Ice/exceptions/Client.ts
Outdated
@@ -55,14 +55,14 @@ export class Client extends TestHelper { | |||
adapter.add(new EmptyI(), Ice.stringToIdentity("")); | |||
test(false); | |||
} catch (ex) { | |||
test(ex instanceof Ice.IllegalIdentityException, ex); | |||
test(ex instanceof Ice.LocalException, ex); |
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 don't get a more specific 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.
Maybe we can use TypeError https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError
@@ -5,11 +5,6 @@ | |||
import { Exception } from "./Exception.js"; | |||
|
|||
export class UserException extends Exception { | |||
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.
Instead of inheriting Exception's ctor, I think UserException should define a ()
constructor. Derived user exceptions should not support setting the error message (and more) at construction time.
js/src/Ice/LocalException.js
Outdated
|
||
static get _id() { | ||
return "::Ice::LocalException"; | ||
constructor(message, 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.
I lean toward simply inheriting the constructor. In particular, when you throw a derived local exception with a cause, we should use the JS error syntax:
throw new MarshalException("Message", { cause: err });
Providing another syntax sounds confusing.
js/src/Ice/LocalExceptions.js
Outdated
constructor(kindOfObject = "", id = "", _cause = "") { | ||
super(_cause); | ||
this.kindOfObject = kindOfObject; | ||
constructor(typeName = "", id = new Ice.Identity(), 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.
typeName should not be defaulted.
js/src/Ice/LocalExceptions.js
Outdated
} | ||
|
||
static get _id() { | ||
return "::Ice::EndpointSelectionTypeParseException"; | ||
constructor(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.
Use inherit ctor.
js/src/Ice/LocalExceptions.js
Outdated
} | ||
|
||
static get _id() { | ||
return "::Ice::VersionParseException"; | ||
constructor(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.
Ditto
js/src/Ice/LocalExceptions.js
Outdated
export class CompressionException extends ProtocolException { | ||
constructor(reason, _cause = "") { | ||
super(reason, _cause); | ||
constructor(strOrProxy) { |
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.
messageOrProxy
would be clearer.
js/src/Ice/LocalExceptions.d.ts
Outdated
constructor(reason?: string, ice_cause?: string | Error); | ||
reason: string; | ||
class RequestFailedException extends LocalException { | ||
constructor(typeName?: string, id?: Identity, facet?: string, operation?: 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.
typeName should not be optional
@@ -82,7 +82,7 @@ export class ServantLocatorI implements Ice.ServantLocator { | |||
if (current.operation == "ice_ids") { | |||
throw new Test.TestIntfUserException(); | |||
} else if (current.operation == "requestFailedException") { | |||
throw new Ice.ObjectNotExistException(); | |||
throw new Ice.ObjectNotExistException(current.id, current.facet, current.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.
It's not clear to me why you don't use the default ctor here.
In general, the preferred/recommended way to throw *NotExistException from application code is without arguments.
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 need to fix the default ctor to not generate a message then, it doesn't work with the refactored code.
Refactoring JavaScript local exceptions, similar to refactoring done in other language mappings.