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

Error message representations #1498

Merged
merged 5 commits into from
Feb 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions distribution/std-lib/Base/src/Data/Any/Extensions.enso
Original file line number Diff line number Diff line change
Expand Up @@ -127,5 +127,5 @@ Any.>> that = x -> that (this x)

Types defining their own versions of this method should ensure that the
result is reasonably small and the operation is quick to compute.
Any.to_display : Text
Any.to_display = this.to_json.to_text
Any.to_default_visualization_data : Text
Any.to_default_visualization_data = this.to_json.to_text
10 changes: 7 additions & 3 deletions distribution/std-lib/Base/src/Error/Extensions.enso
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@ Error.catch (handler = x->x) = this.catch_primitive handler

> Example
Displaying a dataflow error.
(Error.throw "oops!").to_display
Error.to_display : Text
Error.to_display = this.catch .to_display
(Error.throw "oops!").to_default_visualization_data
Error.to_default_visualization_data : Text
Error.to_default_visualization_data = this.catch .to_default_visualization_data

## Returns a human-readable text representing this error.
Error.to_display_text : Text
Error.to_display_text = "Error: " + (this.catch .to_display_text)

## Takes any value, and if it is a dataflow error, throws it as a Panic.
Otherwise, returns the original value unchanged.
Expand Down
4 changes: 2 additions & 2 deletions distribution/std-lib/Table/src/Data/Column.enso
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,8 @@ type Column

Shows a JSON serialization of a truncated version of this column, for the
benefit of visualization in the IDE.
to_display : Text
to_display =
to_default_visualization_data : Text
to_default_visualization_data =
size = ['length', this.length]
name = ['name', this.name]
max_data = 100
Expand Down
3 changes: 2 additions & 1 deletion distribution/std-lib/Table/src/Data/Table.enso
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ type Table
Returns a Text used to display this table in the IDE by default.
Returns a JSON object containing useful metadata and previews of column
values.
to_display =
to_default_visualization_data : Text
to_default_visualization_data =
max_size = 10
nrows = ['number_of_rows', this.nrows]
cols = this.columns.map c->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class ContextFactory {
.option(RuntimeOptions.PACKAGES_PATH, packagesPath)
.option(RuntimeOptions.STRICT_ERRORS, strictErrors.toString)
.option(DebugServerInfo.ENABLE_OPTION, "true")
.option("js.foreign-object-prototype", "true")
.out(out)
.in(in)
.serverTransport { (uri, peer) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.enso.interpreter.node.expression.builtin.error.displaytext;

import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.type.TypesGen;

@BuiltinMethod(type = "Arithmetic_Error", name = "to_display_text")
public abstract class ArithmeticErrorToDisplayTextNode extends Node {
static ArithmeticErrorToDisplayTextNode build() {
return ArithmeticErrorToDisplayTextNodeGen.create();
}

abstract Text execute(Object _this);

@Specialization
Text doAtom(Atom _this) {
try {
return Text.create("Arithmetic error: ", TypesGen.expectText(_this.getFields()[0]));
} catch (UnexpectedResultException e) {
return Text.create("Arithmetic error.");
}
}

@Specialization
Text doConstructor(AtomConstructor _this) {
return Text.create("Arithmetic error.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.enso.interpreter.node.expression.builtin.error.displaytext;

import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.text.Text;

@BuiltinMethod(type = "Arity_Error", name = "to_display_text")
public abstract class ArityErrorToDisplayTextNode extends Node {
static ArityErrorToDisplayTextNode build() {
return ArityErrorToDisplayTextNodeGen.create();
}

abstract Text execute(Object _this);

@Specialization
Text doAtom(Atom _this) {
return Text.create("Wrong number of arguments. Expected ")
.add(String.valueOf(_this.getFields()[0]))
.add(", but got ")
.add(String.valueOf(_this.getFields()[1]))
.add(".");
}

@Specialization
Text doConstructor(AtomConstructor _this) {
return Text.create("Wrong number of arguments.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.enso.interpreter.node.expression.builtin.error.displaytext;

import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.type.TypesGen;

@BuiltinMethod(type = "Compile_Error", name = "to_display_text")
public abstract class CompileErrorToDisplayTextNode extends Node {
static CompileErrorToDisplayTextNode build() {
return CompileErrorToDisplayTextNodeGen.create();
}

abstract Text execute(Object _this);

@Specialization
Text doAtom(Atom _this) {
try {
return Text.create("Compile error: ", TypesGen.expectText(_this.getFields()[0]));
} catch (UnexpectedResultException e) {
return Text.create("Compile error.");
}
}

@Specialization
Text doConstructor(AtomConstructor _this) {
return Text.create("Compile error.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.enso.interpreter.node.expression.builtin.error.displaytext;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.type.TypesGen;

@BuiltinMethod(type = "Inexhaustive_Pattern_Match_Error", name = "to_display_text")
public abstract class InexhaustivePatternMatchErrorToDisplayTextNode extends Node {
static InexhaustivePatternMatchErrorToDisplayTextNode build() {
return InexhaustivePatternMatchErrorToDisplayTextNodeGen.create();
}

abstract Text execute(Object _this);

@Specialization
Text doAtom(Atom _this, @Cached TypeToDisplayTextNode displayTypeNode) {
return Text.create("Inexhaustive pattern match: no branch matches ")
.add(displayTypeNode.execute(_this.getFields()[0]))
.add(".");
}

@Specialization
Text doConstructor(AtomConstructor _this) {
return Text.create("Inexhaustive pattern match.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.enso.interpreter.node.expression.builtin.error.displaytext;

import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.type.TypesGen;

@BuiltinMethod(type = "Invalid_Array_Index_Error", name = "to_display_text")
public abstract class InvalidArrayIndexErrorToDisplayTextNode extends Node {
static InvalidArrayIndexErrorToDisplayTextNode build() {
return InvalidArrayIndexErrorToDisplayTextNodeGen.create();
}

abstract Text execute(Object _this);

@Specialization
Text doAtom(Atom _this) {
return Text.create("Invalid array index: ", String.valueOf(_this.getFields()[1]));
}

@Specialization
Text doConstructor(AtomConstructor _this) {
return Text.create("Invalid array index.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.enso.interpreter.node.expression.builtin.error.displaytext;

import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.type.TypesGen;

@BuiltinMethod(type = "Module_Does_Not_Exist_Error", name = "to_display_text")
public abstract class ModuleDoesNotExistErrorToDisplayTextNode extends Node {
static ModuleDoesNotExistErrorToDisplayTextNode build() {
return ModuleDoesNotExistErrorToDisplayTextNodeGen.create();
}

abstract Text execute(Object _this);

@Specialization
Text doAtom(Atom _this) {
try {
return Text.create("Module ")
.add(TypesGen.expectText(_this.getFields()[0]))
.add(" does not exist.");
} catch (UnexpectedResultException e) {
return Text.create("Module does not exist.");
}
}

@Specialization
Text doConstructor(AtomConstructor _this) {
return Text.create("Module does not exist.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.enso.interpreter.node.expression.builtin.error.displaytext;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.text.Text;

@BuiltinMethod(type = "Module_Not_In_Package_Error", name = "to_display_text")
public class ModuleNotInPackageErrorToDisplayTextNode extends Node {

Text execute(Object _this) {
return Text.create("Module is not a part of a package.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.enso.interpreter.node.expression.builtin.error.displaytext;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.type.TypesGen;

@BuiltinMethod(type = "No_Such_Method_Error", name = "to_display_text")
public abstract class NoSuchMethodErrorToDisplayTextNode extends Node {
static NoSuchMethodErrorToDisplayTextNode build() {
return NoSuchMethodErrorToDisplayTextNodeGen.create();
}

abstract Text execute(Object _this);

@Specialization
Text doAtom(Atom _this, @Cached TypeToDisplayTextNode displayTypeNode) {
try {
return Text.create("Method `")
.add(TypesGen.expectUnresolvedSymbol(_this.getFields()[1]).getName())
.add("` of ")
.add(displayTypeNode.execute(_this.getFields()[0]))
.add(" could not be found.");
} catch (UnexpectedResultException e) {
return Text.create("Method could not be found.");
}
}

@Specialization
Text doConstructor(AtomConstructor _this) {
return Text.create("Method could not be found.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.enso.interpreter.node.expression.builtin.error.displaytext;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.type.TypesGen;

@BuiltinMethod(type = "Not_Invokable_Error", name = "to_display_text")
public abstract class NotInvokableErrorToDisplayTextNode extends Node {
static NotInvokableErrorToDisplayTextNode build() {
return NotInvokableErrorToDisplayTextNodeGen.create();
}

abstract Text execute(Object _this);

@Specialization
Text doAtom(Atom _this, @Cached TypeToDisplayTextNode displayTypeNode) {
return Text.create("Type error: expected a function, but got ")
.add(displayTypeNode.execute(_this.getFields()[0]));
}

@Specialization
Text doConstructor(AtomConstructor _this) {
return Text.create("Type error.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.enso.interpreter.node.expression.builtin.error.displaytext;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.type.TypesGen;

@BuiltinMethod(type = "Polyglot_Error", name = "to_display_text")
public abstract class PolyglotErrorToDisplayTextNode extends Node {
static PolyglotErrorToDisplayTextNode build() {
return PolyglotErrorToDisplayTextNodeGen.create();
}

abstract Text execute(Object _this);

@Specialization
Text doAtom(
Atom _this,
@Cached TypeToDisplayTextNode displayTypeNode,
@CachedLibrary(limit = "5") InteropLibrary exceptions,
@CachedLibrary(limit = "5") InteropLibrary strings) {
try {
Object cause = _this.getFields()[0];
String rep;
if (exceptions.hasExceptionMessage(cause)) {
rep = strings.asString(exceptions.getExceptionCause(cause));
} else {
rep = displayTypeNode.execute(cause);
}
return Text.create("Polyglot error: ").add(rep);
} catch (UnsupportedMessageException e) {
return Text.create("Polyglot error.");
}
}

@Specialization
Text doConstructor(AtomConstructor _this) {
return Text.create("Polyglot error.");
}
}
Loading