Better Module_Does_Not_Exist exception (#11713)

The previous code was throwing `UnknownIdentifierException` when a module wasn't found. That's pretty misleading. Especially when Truffle infrastructure converts such exception to another one. Enso has a dedicated error when module cannot be found. Let's use that one.
This commit is contained in:
Jaroslav Tulach 2024-11-29 20:05:04 +01:00 committed by GitHub
parent 85c8f76805
commit 52feef89ab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 30 additions and 9 deletions

View File

@ -1,9 +1,12 @@
package org.enso.interpreter.runtime; package org.enso.interpreter.runtime;
import static org.enso.scala.wrapper.ScalaConversions.nil; import static org.enso.scala.wrapper.ScalaConversions.nil;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -17,6 +20,7 @@ import org.enso.compiler.data.BindingsMap$ModuleReference$Concrete;
import org.enso.pkg.QualifiedName; import org.enso.pkg.QualifiedName;
import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Engine; import org.graalvm.polyglot.Engine;
import org.graalvm.polyglot.PolyglotException;
import org.graalvm.polyglot.Source; import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.io.IOAccess; import org.graalvm.polyglot.io.IOAccess;
import org.junit.After; import org.junit.After;
@ -52,6 +56,17 @@ public class ModuleTest {
this.ctx = null; this.ctx = null;
} }
@Test
public void noSuchModuleError() {
var b = ctx.getBindings(LanguageInfo.ID);
try {
var r = b.invokeMember(MethodNames.TopScope.GET_MODULE, "Does.Not.Exist.Module");
fail("Expecting failure, but got: " + r);
} catch (PolyglotException ex) {
assertThat(ex.getMessage(), containsString("Module_Does_Not_Exist"));
}
}
@Test @Test
public void moduleKeepsFileRefAfterSourceUnset() { public void moduleKeepsFileRefAfterSourceUnset() {
var name = QualifiedName.simpleName("local.Unnamed_1"); var name = QualifiedName.simpleName("local.Unnamed_1");

View File

@ -272,8 +272,8 @@ public final class EnsoContext {
with root nodes: {r} with root nodes: {r}
""" """
.replace("{n}", "" + n) .replace("{n}", "" + n)
.replace("{s}", "" + n.getEncapsulatingSourceSection()) .replace("{s}", "" + (n != null ? n.getEncapsulatingSourceSection() : null))
.replace("{r}", "" + n.getRootNode())); .replace("{r}", "" + (n != null ? n.getRootNode() : null)));
ex.printStackTrace(); ex.printStackTrace();
checkUntil = System.currentTimeMillis() + 10000; checkUntil = System.currentTimeMillis() + 10000;
var assertsOn = false; var assertsOn = false;

View File

@ -2,6 +2,7 @@ package org.enso.interpreter.runtime.scope;
import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.TruffleFile; import com.oracle.truffle.api.TruffleFile;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.ArityException; import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.InteropLibrary;
@ -10,6 +11,7 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.interop.UnsupportedTypeException; import com.oracle.truffle.api.interop.UnsupportedTypeException;
import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage; import com.oracle.truffle.api.library.ExportMessage;
import com.oracle.truffle.api.nodes.Node;
import java.io.File; import java.io.File;
import java.util.Collection; import java.util.Collection;
import java.util.Optional; import java.util.Optional;
@ -22,6 +24,7 @@ import org.enso.interpreter.runtime.Module;
import org.enso.interpreter.runtime.builtin.Builtins; import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.data.EnsoObject; import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers; import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.type.Types; import org.enso.interpreter.runtime.type.Types;
import org.enso.pkg.Package; import org.enso.pkg.Package;
import org.enso.pkg.QualifiedName; import org.enso.pkg.QualifiedName;
@ -130,7 +133,8 @@ public final class TopLevelScope extends EnsoObject {
var module = scope.getModule(moduleName); var module = scope.getModule(moduleName);
if (module.isEmpty()) { if (module.isEmpty()) {
throw UnknownIdentifierException.create(moduleName); throw new PanicException(
scope.builtins.error().makeModuleDoesNotExistError(moduleName), null);
} }
return module.get(); return module.get();
@ -194,21 +198,23 @@ public final class TopLevelScope extends EnsoObject {
} }
@Specialization @Specialization
static Object doInvoke(TopLevelScope scope, String member, Object[] arguments) static Object doInvoke(
TopLevelScope scope, String member, Object[] arguments, @Bind("$node") Node node)
throws UnknownIdentifierException, ArityException, UnsupportedTypeException { throws UnknownIdentifierException, ArityException, UnsupportedTypeException {
var ctx = EnsoContext.get(node);
switch (member) { switch (member) {
case MethodNames.TopScope.GET_MODULE: case MethodNames.TopScope.GET_MODULE:
return getModule(scope, arguments); return getModule(scope, arguments);
case MethodNames.TopScope.CREATE_MODULE: case MethodNames.TopScope.CREATE_MODULE:
return createModule(scope, arguments, EnsoContext.get(null)); return createModule(scope, arguments, ctx);
case MethodNames.TopScope.REGISTER_MODULE: case MethodNames.TopScope.REGISTER_MODULE:
return registerModule(scope, arguments, EnsoContext.get(null)); return registerModule(scope, arguments, ctx);
case MethodNames.TopScope.UNREGISTER_MODULE: case MethodNames.TopScope.UNREGISTER_MODULE:
return unregisterModule(scope, arguments, EnsoContext.get(null)); return unregisterModule(scope, arguments, ctx);
case MethodNames.TopScope.LEAK_CONTEXT: case MethodNames.TopScope.LEAK_CONTEXT:
return leakContext(EnsoContext.get(null)); return leakContext(ctx);
case MethodNames.TopScope.COMPILE: case MethodNames.TopScope.COMPILE:
return compile(arguments, EnsoContext.get(null)); return compile(arguments, ctx);
default: default:
throw UnknownIdentifierException.create(member); throw UnknownIdentifierException.create(member);
} }