node.js - 将 Rust 与 Neon 绑定(bind)一起使用时,如何获得回溯或以其他方式调试 "failed to initiate panic"?

标签 node.js debugging rust

我使用 Rust + Neon Bindings 编写了一个原生 Node 模块.通用目的是查询数据库,解密结果,并返回一个 JSON 数组给 Node.js。对于某些数据集,这按预期工作,但对于其他数据集,它会引起 panic 。我正在尝试调试它,但是我不知道如何获取堆栈跟踪。唯一的输出是:

fatal runtime error: failed to initiate panic, error 5
    Abort trap: 6

我的调试尝试包括:
  • 包括 Cargo.toml 中的“回溯”
  • 不使用“--release”编译
  • 设置 RUST_BACKTRACE=1DEBUG=true
  • 创建 test.js文件以打印模块
  • 的输出

    构建输出:

    > neon build
    neon info running cargo
      ... all the compilation steps.
      Finished dev [unoptimized + debuginfo] target(s) in 2m 17s
    neon info generating native/index.node
    

    测试文件:

    const Addon = require('./lib');
    const addon = new Addon();
    (async function() {
      console.log(`process.env.RUST_BACKTRACE = ${process.env.RUST_BACKTRACE}`);
      const i = await addon.getData(237);
      console.log(i, i.length)
    }());
    

    测试输出:

    > RUST_BACKTRACE=1 DEBUG=true node test.js 
    process.env.RUST_BACKTRACE = 1
    fatal runtime error: failed to initiate panic, error 5
    Abort trap: 6
    

    对于传递给 addon.getData() 的其他值我按预期取回了 JSON 数据数组。失败的数据集非常大,所以我无法确定任何差异。

    > rustc --version
    rustc 1.38.0 (625451e37 2019-09-23)
    > cargo --version
    cargo 1.38.0 (23ef9a4ef 2019-08-20)
    > node --version
    v11.15.0
    > neon version
    0.3.1
    

    我已经实现了代码的同步版本,以及使用 this example 的异步版本.异步回调在 ./lib/index.js 中转换为 Promise .更新后test.js要使用代码的同步版本,我得到以下输出:

    (node:45229) UnhandledPromiseRejectionWarning: Error: internal error in Neon module: called `Option::unwrap()` on a `None` value
    

    我加了一堆println!() s 到我的代码并能够找到错误(解密的 JSON 对象上缺少必需的属性),但永远无法获得正确的堆栈跟踪。似乎 Neon 必须在异步代码中吞噬它们。

    最佳答案

    我遇到了和你一样的问题,对我来说,我通过使用 match 正确处理结果来解决它。子句和使用 this method处理错误结果,因此回调将在我这边正确生成 NodeJS 错误。

    我的一些片段:

    use std::sync::{Arc, Mutex};
    
    use crate::utils::convert_uids_map;
    
    use neon::prelude::*;
    
    use dgraph_tonic::{DgraphError, Mutation, MutationResponse};
    use dgraph_tonic::sync::{Mutate};
    
    pub struct MutateTask<M> where M: Mutate {
      pub txn: Arc<Mutex<Option<M>>>,
      pub mu: Mutation,
    }
    
    impl<M> Task for MutateTask<M> where M: Mutate + 'static {
      type Output = MutationResponse;
      type Error = DgraphError;
      type JsEvent = JsValue;
    
      fn perform(&self) -> Result<Self::Output, Self::Error> {
        let mut mutex_guard = self.txn.lock().unwrap();
        let txn = mutex_guard.as_mut();
        match txn {
          Some(t) => t.mutate(self.mu.clone()),
          None => Err(DgraphError::EmptyTxn)
        }
      }
    
      fn complete(self, mut ctx: TaskContext, result: Result<Self::Output, Self::Error>) -> JsResult<Self::JsEvent> {
        match result {
          Ok(x) => Ok(convert_uids_map(&mut ctx, &x.uids).unwrap().upcast()),
          Err(e) => ctx.throw_error(format!("MutateTask Error - {:?}", e))
        }
      }
    }
    

    然后我得到有意义的错误继续:
    (node:50781) UnhandledPromiseRejectionWarning: Error: MutateTask Error - GrpcError(CannotDoRequest(Status { code: Unknown, message: "key error: subject:\"_:dg.1759080630.67\" predicate:\"@timestamp\" object_value:<str_val:\"2020-04-28T02:22:19.570Z\" > : predicate \"@timestamp\": Has invalid characters" }))
    (node:50781) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
    (node:50781) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
    

    关于node.js - 将 Rust 与 Neon 绑定(bind)一起使用时,如何获得回溯或以其他方式调试 "failed to initiate panic"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58595477/

    相关文章:

    rust - 如何使用 std::num::sqrt 计算数字的平方根?

    string - 我如何在 Rust 中加入一个字符向量

    node.js - 解决无法建立网络隧道套接字错误

    node.js - Electron 错误AVDCreateGPUAccelerator : Error loading GPU renderer

    node.js - 使用 Lusca 的 hackathon-starter - csrf 值在哪里计算/存储?

    node.js - Node js SOAP 库与 DateAdvance 一词相关的问题

    Python 断言——改进了失败的自省(introspection)?

    rust - 为什么 Option<&String> 不强制转换为 Option<&str>?

    javascript - 将所有 JavaScript 语句输出到控制台

    C++ bughunt - vector 中的高分插入会使程序崩溃