Skip to content
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

Merged
merged 5 commits into from
Jul 26, 2024
Merged

Conversation

pepone
Copy link
Member

@pepone pepone commented Jul 25, 2024

Refactoring JavaScript local exceptions, similar to refactoring done in other language mappings.

@pepone pepone requested review from externl and bernardnormier July 25, 2024 18:07
@@ -2,87 +2,12 @@
// Copyright (c) ZeroC, Inc. All rights reserved.
//

const toString = function (key, object, objectTable, ident) {
Copy link
Member Author

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.

Copy link
Member

@bernardnormier bernardnormier Jul 25, 2024

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.

Copy link
Member Author

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) {
Copy link
Member Author

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.

See https://playcode.io/1950124

*
* @return The string representation of the object identity.
**/
export function identityToString(ident, toStringMode = ToStringMode.Unicode) {
Copy link
Member Author

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));
// }
Copy link
Member Author

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.

Copy link
Member

@bernardnormier bernardnormier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.


export function throwUOE(expectedType, v) {
// If the object is an unknown sliced object, we didn't find an value factory.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a value factory

"expected element of type `" + expectedType + "' but received `" + type + "'",
type,
expectedType,
let expected = expectedType.ice_staticId(); // TODO add ice_staticId
Copy link
Member

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.

@@ -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);
Copy link
Member

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -5,11 +5,6 @@
import { Exception } from "./Exception.js";

export class UserException extends Exception {
constructor() {
Copy link
Member

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.


static get _id() {
return "::Ice::LocalException";
constructor(message, cause) {
Copy link
Member

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.

constructor(kindOfObject = "", id = "", _cause = "") {
super(_cause);
this.kindOfObject = kindOfObject;
constructor(typeName = "", id = new Ice.Identity(), facet = "", operation = "") {
Copy link
Member

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.

}

static get _id() {
return "::Ice::EndpointSelectionTypeParseException";
constructor(message) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use inherit ctor.

}

static get _id() {
return "::Ice::VersionParseException";
constructor(message) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

export class CompressionException extends ProtocolException {
constructor(reason, _cause = "") {
super(reason, _cause);
constructor(strOrProxy) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

messageOrProxy would be clearer.

constructor(reason?: string, ice_cause?: string | Error);
reason: string;
class RequestFailedException extends LocalException {
constructor(typeName?: string, id?: Identity, facet?: string, operation?: string);
Copy link
Member

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

@bernardnormier bernardnormier self-requested a review July 26, 2024 13:34
@@ -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);
Copy link
Member

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.

Copy link
Member Author

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.

@pepone pepone merged commit 806f28c into zeroc-ice:main Jul 26, 2024
7 checks passed
@pepone pepone mentioned this pull request Aug 2, 2024
9 tasks
InsertCreativityHere pushed a commit to InsertCreativityHere/compiler-comparison that referenced this pull request Jan 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants