我在一个Java应用程序上工作,该应用程序大量使用Javascript来形成业务逻辑/胶水。它使用Graal运行。一切正常,但是我们在有效的错误处理方面遇到了困难。
这实际上就是执行JS的方式:
try {
Context context = Context.newBuilder("js").allowAllAccess(true).build()
Source s = Source.newBuilder("js", src, "script").build();
context.eval(s);
} catch (Exception e) {
LOGGER.error("Exception occurred in JavaScript:...", e);
}
因此,当发生错误时,我们会将它们记录在某个地方,以便我们进行事后检查等。可以从Graal抛出的PolyglotException
中获取这些日志中的JS堆栈跟踪,这很好。但是,当某些JS代码返回到Java领域并且引发了Java异常时,事情就更加复杂了:
var x = callJavaFunction("invalid parameter"); // Throws a NoSuchElementException, for example
PolyglotException
具有一个asHostException()
方法,该方法返回原始的Java-land异常,而我执行JS文件的代码足够聪明,可以理解这一点并生成有用的错误日志。 由于某种原因,当JS代码试图自行捕获时,就会出现问题:
try {
var x = callJavaFunction("invalid parameter"); // NoSuchElementException
} catch (e) {
doSomeCleanup();
throw e;
}
现在,我们已经丢失了原始异常,更糟糕的是,JS-stack跟踪现在仅向我们显示了catch
块,而不是原因所在。 isHostException()
返回false
,因为现在这只是一个JS错误。我找不到找到原始原因的方法,这使得诊断错误非常困难,尤其是当错误是从生产系统中发出时。原始的Java异常消息以JS-error对象结尾,这很有用,但是我们没有堆栈跟踪,这不是。
我可以采取什么方法来解决这个问题?
我曾经有一个想法:每当引发主机异常时,我可以挂接到GraalVM并获取回调吗?至少以这种方式,我可以拥有一条日志,上面写着“在执行过程中引发了以下Java异常”,该日志可以附加到错误报告中。到目前为止,我还没有找到实现这一目标的方法。