Skip to content

Commit 8e8f129

Browse files
RaisinTenjuanarbol
authored andcommitted
src: properly report exceptions from AddressToJS()
Signed-off-by: Darshan Sen <[email protected]> PR-URL: #42054 Reviewed-By: Matteo Collina <[email protected]>
1 parent 3b810ca commit 8e8f129

8 files changed

+67
-16
lines changed

lib/dgram.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ function startListening(socket) {
159159
const state = socket[kStateSymbol];
160160

161161
state.handle.onmessage = onMessage;
162-
// Todo: handle errors
162+
state.handle.onerror = onError;
163163
state.handle.recvStart();
164164
state.receiving = true;
165165
state.bindState = BIND_STATE_BOUND;
@@ -923,6 +923,12 @@ function onMessage(nread, handle, buf, rinfo) {
923923
}
924924

925925

926+
function onError(nread, handle, error) {
927+
const self = handle[owner_symbol];
928+
return self.emit('error', error);
929+
}
930+
931+
926932
Socket.prototype.ref = function() {
927933
const handle = this[kStateSymbol].handle;
928934

src/js_udp_wrap.cc

+10-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
#include <algorithm>
77

8+
// TODO(RaisinTen): Replace all uses with empty `v8::Maybe`s.
9+
#define JS_EXCEPTION_PENDING UV_EPROTO
10+
811
namespace node {
912

1013
using errors::TryCatchScope;
@@ -60,7 +63,7 @@ int JSUDPWrap::RecvStart() {
6063
Context::Scope context_scope(env()->context());
6164
TryCatchScope try_catch(env());
6265
Local<Value> value;
63-
int32_t value_int = UV_EPROTO;
66+
int32_t value_int = JS_EXCEPTION_PENDING;
6467
if (!MakeCallback(env()->onreadstart_string(), 0, nullptr).ToLocal(&value) ||
6568
!value->Int32Value(env()->context()).To(&value_int)) {
6669
if (try_catch.HasCaught() && !try_catch.HasTerminated())
@@ -74,7 +77,7 @@ int JSUDPWrap::RecvStop() {
7477
Context::Scope context_scope(env()->context());
7578
TryCatchScope try_catch(env());
7679
Local<Value> value;
77-
int32_t value_int = UV_EPROTO;
80+
int32_t value_int = JS_EXCEPTION_PENDING;
7881
if (!MakeCallback(env()->onreadstop_string(), 0, nullptr).ToLocal(&value) ||
7982
!value->Int32Value(env()->context()).To(&value_int)) {
8083
if (try_catch.HasCaught() && !try_catch.HasTerminated())
@@ -90,7 +93,7 @@ ssize_t JSUDPWrap::Send(uv_buf_t* bufs,
9093
Context::Scope context_scope(env()->context());
9194
TryCatchScope try_catch(env());
9295
Local<Value> value;
93-
int64_t value_int = UV_EPROTO;
96+
int64_t value_int = JS_EXCEPTION_PENDING;
9497
size_t total_len = 0;
9598

9699
MaybeStackBuffer<Local<Value>, 16> buffers(nbufs);
@@ -100,10 +103,13 @@ ssize_t JSUDPWrap::Send(uv_buf_t* bufs,
100103
total_len += bufs[i].len;
101104
}
102105

106+
Local<Object> address;
107+
if (!AddressToJS(env(), addr).ToLocal(&address)) return value_int;
108+
103109
Local<Value> args[] = {
104110
listener()->CreateSendWrap(total_len)->object(),
105111
Array::New(env()->isolate(), buffers.out(), nbufs),
106-
AddressToJS(env(), addr)
112+
address,
107113
};
108114

109115
if (!MakeCallback(env()->onwrite_string(), arraysize(args), args)

src/node_internals.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class Environment;
5858
// Convert a struct sockaddr to a { address: '1.2.3.4', port: 1234 } JS object.
5959
// Sets address and port properties on the info object and returns it.
6060
// If |info| is omitted, a new object is returned.
61-
v8::Local<v8::Object> AddressToJS(
61+
v8::MaybeLocal<v8::Object> AddressToJS(
6262
Environment* env,
6363
const sockaddr* addr,
6464
v8::Local<v8::Object> info = v8::Local<v8::Object>());

src/node_sockaddr-inl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ void SocketAddress::Update(const sockaddr* data, size_t len) {
157157
memcpy(&address_, data, len);
158158
}
159159

160-
v8::Local<v8::Object> SocketAddress::ToJS(
160+
v8::MaybeLocal<v8::Object> SocketAddress::ToJS(
161161
Environment* env,
162162
v8::Local<v8::Object> info) const {
163163
return AddressToJS(env, data(), info);

src/node_sockaddr.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,9 @@ void SocketAddressBase::LegacyDetail(const FunctionCallbackInfo<Value>& args) {
847847
Environment* env = Environment::GetCurrent(args);
848848
SocketAddressBase* base;
849849
ASSIGN_OR_RETURN_UNWRAP(&base, args.Holder());
850-
args.GetReturnValue().Set(base->address_->ToJS(env));
850+
Local<Object> address;
851+
if (!base->address_->ToJS(env).ToLocal(&address)) return;
852+
args.GetReturnValue().Set(address);
851853
}
852854

853855
SocketAddressBase::SocketAddressBase(

src/node_sockaddr.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class SocketAddress : public MemoryRetainer {
131131
static SocketAddress FromPeerName(const uv_udp_t& handle);
132132
static SocketAddress FromPeerName(const uv_tcp_t& handle);
133133

134-
inline v8::Local<v8::Object> ToJS(
134+
inline v8::MaybeLocal<v8::Object> ToJS(
135135
Environment* env,
136136
v8::Local<v8::Object> obj = v8::Local<v8::Object>()) const;
137137

src/tcp_wrap.cc

+4-5
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,9 @@ void TCPWrap::Connect(const FunctionCallbackInfo<Value>& args,
342342

343343

344344
// also used by udp_wrap.cc
345-
Local<Object> AddressToJS(Environment* env,
346-
const sockaddr* addr,
347-
Local<Object> info) {
345+
MaybeLocal<Object> AddressToJS(Environment* env,
346+
const sockaddr* addr,
347+
Local<Object> info) {
348348
EscapableHandleScope scope(env->isolate());
349349
char ip[INET6_ADDRSTRLEN + UV_IF_NAMESIZE];
350350
const sockaddr_in* a4;
@@ -371,8 +371,7 @@ Local<Object> AddressToJS(Environment* env,
371371
&scopeidlen);
372372
if (r) {
373373
env->ThrowUVException(r, "uv_if_indextoiid");
374-
// TODO(addaleax): Do proper MaybeLocal handling here
375-
return scope.Escape(info);
374+
return {};
376375
}
377376
}
378377
port = ntohs(a6->sin6_port);

src/udp_wrap.cc

+40-2
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@
2222
#include "udp_wrap.h"
2323
#include "env-inl.h"
2424
#include "node_buffer.h"
25+
#include "node_errors.h"
2526
#include "node_sockaddr-inl.h"
2627
#include "handle_wrap.h"
2728
#include "req_wrap-inl.h"
2829
#include "util-inl.h"
2930

3031
namespace node {
3132

33+
using errors::TryCatchScope;
3234
using v8::Array;
3335
using v8::ArrayBuffer;
3436
using v8::BackingStore;
@@ -728,9 +730,45 @@ void UDPWrap::OnRecv(ssize_t nread,
728730
bs = BackingStore::Reallocate(isolate, std::move(bs), nread);
729731
}
730732

733+
Local<Object> address;
734+
{
735+
bool has_caught = false;
736+
{
737+
TryCatchScope try_catch(env);
738+
if (!AddressToJS(env, addr).ToLocal(&address)) {
739+
DCHECK(try_catch.HasCaught() && !try_catch.HasTerminated());
740+
argv[2] = try_catch.Exception();
741+
DCHECK(!argv[2].IsEmpty());
742+
has_caught = true;
743+
}
744+
}
745+
if (has_caught) {
746+
DCHECK(!argv[2].IsEmpty());
747+
MakeCallback(env->onerror_string(), arraysize(argv), argv);
748+
return;
749+
}
750+
}
751+
731752
Local<ArrayBuffer> ab = ArrayBuffer::New(isolate, std::move(bs));
732-
argv[2] = Buffer::New(env, ab, 0, ab->ByteLength()).ToLocalChecked();
733-
argv[3] = AddressToJS(env, addr);
753+
{
754+
bool has_caught = false;
755+
{
756+
TryCatchScope try_catch(env);
757+
if (!Buffer::New(env, ab, 0, ab->ByteLength()).ToLocal(&argv[2])) {
758+
DCHECK(try_catch.HasCaught() && !try_catch.HasTerminated());
759+
argv[2] = try_catch.Exception();
760+
DCHECK(!argv[2].IsEmpty());
761+
has_caught = true;
762+
}
763+
}
764+
if (has_caught) {
765+
DCHECK(!argv[2].IsEmpty());
766+
MakeCallback(env->onerror_string(), arraysize(argv), argv);
767+
return;
768+
}
769+
}
770+
771+
argv[3] = address;
734772
MakeCallback(env->onmessage_string(), arraysize(argv), argv);
735773
}
736774

0 commit comments

Comments
 (0)