Skip to content

Commit

Permalink
Error message representations (#1498)
Browse files Browse the repository at this point in the history
  • Loading branch information
kustosz authored and iamrecursion committed Feb 23, 2021
1 parent 9282710 commit 6adcb41
Show file tree
Hide file tree
Showing 32 changed files with 738 additions and 42 deletions.
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

0 comments on commit 6adcb41

Please sign in to comment.