0

我可以通过推送一个错误对象然后调用 duk_throw() 在 C++ 代码中抛出错误。duk_pcall() 返回“结果!= DUK_EXEC_SUCCESS”,我可以检查错误对象以确定,例如,调用我的 API 的行号。一切正常,谢谢。

如果脚本使用 EMCAscript throw( ) 抛出错误,duk_pcall( ) 将返回 'outcome != DUK_EXEC_SUCCESS' ,但堆栈上没有错误对象。所以我无法确定行号。由于 throw 可能在使用 require() 加载的脚本中并且对用户不可见,因此很遗憾。

是否可以从 ECMAscript throw() 中获取错误对象?

4

2 回答 2

0

仔细检查你的发现。duk_pcall对我来说,失败时 TOS 上有一个错误对象:

    result = duk_pcall(_ctx, static_cast<duk_idx_t>(argCount));
    if (result != DUK_EXEC_SUCCESS)
      checkForErrors();

错误检查是:

/**
 * Checks if the TOS contains a JS error object and throws a C++ exception for it. This is particularly useful
 * when executing code in safe mode (pcall).
 */
void ScriptingContext::checkForErrors() const {
  if (duk_is_error(_ctx, -1)) {
    // See if there's a stack trace. That includes the actual error message so we can use
    // that as exception message. Otherwise just get what is on stack top.
    std::string error;
    if (duk_has_prop_string(_ctx, -1, "stack")) {
      duk_get_prop_string(_ctx, -1, "stack"); // Puts stack trace on the stack.
      error = duk_require_string(_ctx, -1);
    } else {
      error = duk_safe_to_string(_ctx, -1);
    }
    duk_pop(_ctx); // Remove error from stack.

    throw std::runtime_error(error);
  }
}
于 2021-04-11T09:52:16.500 回答
0

感谢您的评论。对我来说不是。

我有:

startTimeout();
duk_int_t dukOutcome = duk_peval(mpCtx);    // run code
clearTimeout();
if (dukOutcome != DUK_EXEC_SUCCESS){
    if (duk_is_error(mpCtx, -1)){
         wxString formErrorMessage(duk_context *ctx);
         m_result = formErrorMessage(mpCtx);
         }
    else m_result = duk_safe_to_string(mpCtx, -1);
    duk_pop(mpCtx);
    return ERROR;
    }

如果如我在我的 OP 中描述的那样在 C++ 代码中引发错误,则会调用 formErrorMessage。如果错误是由于 JavaScript throw("Message"); 声明,duk_is_error(mpCtx, -1))为 false 并且不采用 formErrorMessage 路由。我在 Xcode 下跟踪这个,可以看到到底发生了什么。我们之间可能有一些不同的配置选项吗?

Duktape v2.5.0 wxWidgets v3.1.2

于 2021-04-12T12:31:04.187 回答