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

Please don't use toString when printing NoSuchMethodException #546

Closed
peter-ahe-google opened this issue Nov 21, 2011 · 9 comments
Closed
Assignees
Labels
area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends.
Milestone

Comments

@peter-ahe-google
Copy link
Contributor

It would be nice if the VM would tell me the class name, not the result of calling toString when throwing a NoSuchMethodException.

Otherwise, things like this is hard to debug:

class Fisk {
  toString() => "1";
}

class Hest {
  toString() { throw "hest"; }
}

main() {
  try {
    1 + new Fisk();
  } catch (var e) {
    print(e);
  }
  1 + new Hest();
}

Right now the VM says:

NoSuchMethodException - receiver: '1' function name: 'addFromInteger' arguments: [1]]
Unhandled exception:
<Received exception while converting exception to string>
 0. Function: 'Object.noSuchMethod' url: 'bootstrap' line:315 col:3
 1. Function: 'IntegerImplementation.+' url: 'bootstrap_impl' line:1463 col:32
 2. Function: '::.main' url: '/Users/ahe/Dart/all/dart.googlecode.com/dart/frog/fisk.dart' line:15 col:5

These examples are silly, but very similar issues are making it hard to debug problems in Frog/Leg.

@peter-ahe-google
Copy link
Contributor Author

This is also confusing:

class Fisk {
  toString() => "";
}

main() {
  new Object().toString(new Fisk());
}

NoSuchMethodException - receiver: 'Instance of 'Object'' function name: 'toString' arguments: []]
 0. Function: 'Object.noSuchMethod' url: 'bootstrap' line:315 col:3
 1. Function: '::.main' url: '/Users/ahe/Dart/all/dart.googlecode.com/dart/frog/fisk.dart' line:6 col:24

@iposva-google
Copy link
Contributor

To understand better what Peter means with his second example from comment 1:

main() {
  new Object().toString(1);
}

produces

Unhandled exception:
NoSuchMethodException - receiver: 'Instance of 'Object'' function name: 'toString' arguments: [1]]
 0. Function: 'Object.noSuchMethod' url: 'bootstrap' line:350 col:3
 1. Function: '::.main' url: 'Issue546.dart' line:2 col:24

Note that the parameter is printed here. Maybe we should also print the class name of the parameter or the position of the parameter, such as:
NoSuchMethodException - receiver: 'Instance of 'Object'' function name: 'toString' arguments: [1: "1"]]

I assume this will be revised when we address the general problems of NoSuchMethod handling.

@iposva-google
Copy link
Contributor

Issue #420 has been merged into this issue.

@iposva-google
Copy link
Contributor

Set owner to @sgmitrovic.
Added Accepted label.

@sethladd
Copy link
Contributor

sethladd commented May 6, 2012

Is this still valid?

@peter-ahe-google
Copy link
Contributor Author

I think this bug is still valid. The error message is slightly different (as in much better):

NoSuchMethodException : method not found: 'addFromInteger'
Receiver: 1
Arguments: [1]
Unhandled exception:
<Received error while converting exception to string>
 0. Function: 'Object.noSuchMethod' url: 'bootstrap' line:717 col:3
 1. Function: 'IntegerImplementation.+' url: 'bootstrap_impl' line:1428 col:32
 2. Function: '::main' url: 'file:///Users/ahe/Dart/all/dart/fisk.dart' line:15 col:5

The information I would like to have in the first part is the classes of the receiver and arguments, for example:

NoSuchMethodException : method not found: 'addFromInteger'
Receiver: int(1)
Arguments: [1]

Also, if toString is broken, it hides the original exception:

Unhandled exception:
<Received error while converting exception to string>
 0. Function: 'Object.noSuchMethod' url: 'bootstrap' line:717 col:3
 1. Function: 'IntegerImplementation.+' url: 'bootstrap_impl' line:1428 col:32
 2. Function: '::main' url: 'file:///Users/ahe/Dart/all/dart/fisk.dart' line:15 col:5

In addition, there is no stack trace for the broken toString method.

Here is one possible solution to this problem:

Add a private helper method to Object:

String _toExceptionString() {
  String classname = /* native call */;
  String result;
  try {
    result = '$classname("${toString}()")';
  } finally {
    if (result === null) {
      result = '<Error when calling $classname.toString.>';
    }
    // Ignore any exceptions.
    return result;
  }
}

Override this method in String, int, and double implementations. For example, in Smi:

String _toExceptionString() => 'int(${toString()})';

@ghost
Copy link

ghost commented Aug 29, 2012

Added this to the M2 milestone.

@ghost
Copy link

ghost commented Dec 4, 2012

Is this still valid, I think this has been fixed by library team.

@peter-ahe-google
Copy link
Contributor Author

I fixed this in r12533.


Set owner to @peter-ahe-google.
Added Fixed label.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends.
Projects
None yet
Development

No branches or pull requests

3 participants