返回顶部
首页 > 资讯 > 前端开发 > VUE >Nodejs中怎么对错误进行处理
  • 141
分享到

Nodejs中怎么对错误进行处理

2024-04-02 19:04:59 141人浏览 泡泡鱼
摘要

今天就跟大家聊聊有关nodejs中怎么对错误进行处理,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。假设我们有以下代码const net&n

今天就跟大家聊聊有关nodejs中怎么对错误进行处理,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

假设我们有以下代码

const net = require('net');  net.connect({port: 9999})

如果本机上没有监听9999端口,那么我们会得到以下输出。

events.js:170          throw er; // Unhandled 'error' event          ^        Error: connect ECONNREFUSED 127.0.0.1:9999        at tcpConnectWrap.afterConnect [as oncomplete] (net.js:1088:14)    Emitted 'error' event at:        at emitErrorNT (internal/streams/destroy.js:91:8)        at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)        at processTicksAndRejections (internal/process/task_queues.js:81:17)

我们简单看一下connect的调用流程。

const req = new TCPConnectWrap();   req.oncomplete = afterConnect;   req.address = address;   req.port = port;   req.localAddress = localAddress;   req.localPort = localPort;   // 开始三次握手建立连接   err = self._handle.connect(req, address, port);

接着我们看一下c++层connect的逻辑

err = req_wrap->Dispatch(uv_tcp_connect,                   &wrap->handle_,                   reinterpret_cast(&addr),                   AfterConnect);

C++层直接调用Libuv的uv_tcp_connect,并且设置回调是AfterConnect。接着我们看libuv的实现。

do {       errno = 0;       // 非阻塞调用       r = connect(uv__stream_fd(handle), addr, addrlen);     } while (r == -1 && errno == EINTR);     // 连接错误,判断错误码     if (r == -1 && errno != 0) {       // 还在连接中,不是错误,等待连接完成,事件变成可读       if (errno == EINPROGRESS)         ;        else if (errno == ECONNREFUSED)         // 连接被拒绝         handle->delayed_error = UV__ERR(ECONNREFUSED);       else         return UV__ERR(errno);     }     uv__req_init(handle->loop, req, UV_CONNECT);     req->cb = cb;     req->handle = (uv_stream_t*) handle;     QUEUE_INIT(&req->queue);     // 挂载到handle,等待可写事件     handle->connect_req = req;   uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);

我们看到Libuv以异步的方式调用操作系统,然后把request挂载到handle中,并且注册等待可写事件,当连接失败的时候,就会执行uv__stream_io回调,我们看一下Libuv的处理(uv__stream_io)。

getsockopt(uv__stream_fd(stream),                  SOL_Socket,                  SO_ERROR,                  &error,                  &errorsize);   error = UV__ERR(error);   if (req->cb)       req->cb(req, error);

获取错误信息后回调C++层的AfterConnect。

Localargv[5] = {      Integer::New(env->isolate(), status),      wrap->object(),      req_wrap->object(),      Boolean::New(env->isolate(), readable),      Boolean::New(env->isolate(), writable)    };       req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv);

接着调用JS层的oncomplete回调。

const ex = exceptionWithHostPort(status,                                    'connect',                                    req.address,                                    req.port,                                    details);   if (details) {     ex.localAddress = req.localAddress;     ex.localPort = req.localPort;   }   // 销毁socket   self.destroy(ex);

exceptionWithHostPort构造错误信息,然后销毁socket并且以ex为参数触发error事件。我们看看uvExceptionWithHostPort的实现。

function uvExceptionWithHostPort(err, syscall, address, port) {     const [ code, uvmsg ] = uvErrmapGet(err) || uvUnmappedError;     const message = `${syscall} ${code}: ${uvmsg}`;     let details = '';        if (port && port > 0) {       details = ` ${address}:${port}`;     } else if (address) {       details = ` ${address}`;     }     const tmpLimit = Error.stackTraceLimit;     Error.stackTraceLimit = 0;     const ex = new Error(`${message}${details}`);     Error.stackTraceLimit = tmpLimit;     ex.code = code;     ex.errno = err;     ex.syscall = syscall;     ex.address = address;     if (port) {       ex.port = port;     }     // 获取调用栈信息但不包括当前调用的函数uvExceptionWithHostPort,注入stack字段到ex中     Error.captureStackTrace(ex, excludedStackFn || uvExceptionWithHostPort);     return ex;   }

我们看到错误信息主要通过uvErrmapGet获取

unction uvErrmapGet(name) {      uvBinding = lazyUv();      if (!uvBinding.errmap) {        uvBinding.errmap = uvBinding.getErrORMap();      }      return uvBinding.errmap.get(name);    }        function lazyUv() {      if (!uvBinding) {        uvBinding = internalBinding('uv');      }      return uvBinding;    }

继续往下看,uvErrmapGet调用了C++层的uv模块的getErrorMap。

void GetErrMap(const FunctionCallbackInfo& args) {     Environment* env = Environment::GetCurrent(args);     Isolate* isolate = env->isolate();     Localcontext = env->context();        Local   // 从per_process::uv_errors_map中获取错误信息     size_t errors_len = arraysize(per_process::uv_errors_map);     // 赋值     for (size_t i = 0; i < errors_len; ++i) {        // map的键是 uv_errors_map每个元素中的value,值是name和message     const auto& error = per_process::uv_errors_map[i];       Localarr[] = {OneByteString(isolate, error.name),                             OneByteString(isolate, error.message)};      if (err_map               ->Set(context,                     Integer::New(isolate, error.value),                     Array::New(isolate, arr, arraysize(arr)))               .IsEmpty()) {         return;       }     }        args.GetReturnValue().Set(err_map);   }

我们看到错误信息存在per_process::uv_errors_map中,我们看一下uv_errors_map的定义。

struct UVError {   int value;   const char* name;   const char* message; };  static const struct UVError uv_errors_map[] = {   #define V(name, message) {UV_##name, #name, message},       UV_ERRNO_MAP(V)   #undef V   };

UV_ERRNO_MAP宏展开后如下

{UV_E2BIG, "E2BIG", "argument list too long"},   {UV_EACCES, "EACCES", "permission denied"},   {UV_EADDRINUSE, "EADDRINUSE", "address already in use"},   &hellip;&hellip;

所以导出到JS层的结果如下

{     // 键是一个数字,由Libuv定义,其实是封装了操作系统的定义   UV_ECONNREFUSED: ["ECONNREFUSED", "connection refused"],       UV_ECONNRESET: ["ECONNRESET", "connection reset by peer"]      ...    }

node.js最后会组装这些信息返回给调用方。这就是我们输出的错误信息。那么为什么会是ECONNREFUSED呢?我们看一下操作系统对于该错误码的逻辑。

static void tcp_reset(struct sock *sk)   {       switch (sk->sk_state) {           case TCP_SYN_SENT:               sk->sk_err = ECONNREFUSED;               break;            // ...     }      }

当操作系统收到一个发给该socket的rst包的时候会执行tcp_reset,我们看到当socket处于发送syn包等待ack的时候,如果收到一个fin包,则会设置错误码为ECONNREFUSED。我们输出的正是这个错误码。

看完上述内容,你们对nodejs中怎么对错误进行处理有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网VUE频道,感谢大家的支持。

--结束END--

本文标题: Nodejs中怎么对错误进行处理

本文链接: https://lsjlt.com/news/74269.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Nodejs中怎么对错误进行处理
    今天就跟大家聊聊有关Nodejs中怎么对错误进行处理,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。假设我们有以下代码const net&n...
    99+
    2024-04-02
  • Golang中怎么对错误进行处理
    这期内容当中小编将会给大家带来有关Golang中怎么对错误进行处理,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。首先介绍几种常见的创建错误的方法基于字符串的错误err1&...
    99+
    2024-04-02
  • NodeJs中怎么对数据库异常进行处理
    NodeJs中怎么对数据库异常进行处理,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。数据库链接错误使用nodejs处理异常最麻...
    99+
    2024-04-02
  • 使用nodejs怎么对tcp连接进行处理
    今天就跟大家聊聊有关使用nodejs怎么对tcp连接进行处理,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。int uv_tcp_listen(uv_tcp_t* ...
    99+
    2023-06-06
  • vbScript中如何进行错误处理
    这篇文章将为大家详细讲解有关vbScript中如何进行错误处理,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。vbscript中,错误处理使用on error resume next来完成,如果在你的代码里...
    99+
    2023-06-08
  • go goroutine 怎样进行错误处理
    目录前言 通过错误日志记录 利用 channel 传输 使用 sync/errgroup 总结 前言 在 Go 语言程序开发中,goroutine 的使用是比较频繁的,因此在日常编...
    99+
    2024-04-02
  • NodeJS处理Express中异步错误
    摘要 比起回调函数,使用 Promise 来处理异步错误要显得优雅许多。 结合 Express 内置的错误处理机制和 Promise 极大地降低产生未捕获错误(uncaught exception)的可能性...
    99+
    2022-06-04
    错误 NodeJS Express
  • Nodejs怎么进行多线程处理
    这篇文章主要介绍Nodejs怎么进行多线程处理,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Threads à gogo 是nodejs 的原生模块,使用这个模块可以让nodejs 具备多线程处理功能。【推荐学习:《...
    99+
    2023-06-15
  • PHP中PDO如何进行错误处理
    这篇文章给大家分享的是有关PHP中PDO如何进行错误处理的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。在之前的学习中我们已经学会出来了通过PDO获取查询结果,那接下来就要学习一下PDO的错误处理, 在 PDO 中...
    99+
    2023-06-25
  • thinkphp5中怎么进行错误处理的相关信息
    本篇内容介绍了“thinkphp5中怎么进行错误处理的相关信息”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!错误处理机制ThinkPHP5提...
    99+
    2023-07-05
  • VB中怎么进行错误处理和异常捕获
    在VB中,可以使用Try-Catch语句块来处理错误和捕获异常。下面是一个简单的示例: Try ' 可能会引发异常的代码 C...
    99+
    2024-04-03
    VB
  • Node.js中怎么对CORS进行处理
    今天就跟大家聊聊有关Node.js中怎么对CORS进行处理,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。什么是CORSCORS 是“跨域资源共享”的...
    99+
    2024-04-02
  • Android中怎么对cookie进行处理
    本篇文章给大家分享的是有关Android中怎么对cookie进行处理,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。android 客户端 Cookie处理Cookie,有时也用...
    99+
    2023-05-30
    android cookie
  • golang如何进行错误处理
    这篇“golang如何进行错误处理”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“golang如何进行错误处理”文章吧。Gol...
    99+
    2023-07-04
  • Nginx中怎么对图片进行处理
    本篇文章给大家分享的是有关Nginx中怎么对图片进行处理,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Nginx图片处理一个网管员必备的数据处...
    99+
    2024-04-02
  • 怎么在Python中对Args进行处理
    这篇文章将为大家详细讲解有关怎么在Python中对Args进行处理,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。1. sys 模块Python 中的 sys 模块具有 argv 功能。当通过...
    99+
    2023-06-14
  • Python中怎么对文件进行处理
    本篇文章给大家分享的是有关Python中怎么对文件进行处理,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。建议一:使用 pathlib 模块如果你需要在 Python 里进行文件...
    99+
    2023-06-15
  • node中怎么对日志进行处理
    本篇文章为大家展示了node中怎么对日志进行处理,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、技术选型选择了3种主流的技术进行对比:1.1 log4jslog4js是一种node日志管理工具,可...
    99+
    2023-06-03
  • 怎么在pandas apply中对并行进行处理
    怎么在pandas apply中对并行进行处理?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1. pandarallel (pip install )对于一个带有Panda...
    99+
    2023-06-06
  • 使用Raygun对Node.js应用进行错误处理的方法
    用我们的 raygun4node 包,能提供一种把您的Node.js错误发送给Raygun的便利办法. 它可以很容仪的使用 npm 安装: npm install raygun 其能给您提供一...
    99+
    2022-06-04
    错误 方法 Raygun
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作