Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BREAKING(ext/net): improved error code accuracy #25383

Merged
merged 3 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion ext/net/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ impl From<SocketAddr> for IpAddr {
}

pub(crate) fn accept_err(e: std::io::Error) -> AnyError {
// FIXME(bartlomieju): compatibility with current JS implementation
if let std::io::ErrorKind::Interrupted = e.kind() {
bad_resource("Listener has been closed")
} else {
Expand Down
7 changes: 3 additions & 4 deletions ext/net/ops_tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,10 @@ where
.resource_table
.take::<TcpStreamResource>(rid)?;
// This TCP connection might be used somewhere else. If it's the case, we cannot proceed with the
// process of starting a TLS connection on top of this TCP connection, so we just return a bad
// resource error. See also: https://github.com/denoland/deno/pull/16242
// process of starting a TLS connection on top of this TCP connection, so we just return a Busy error.
// See also: https://github.com/denoland/deno/pull/16242
let resource = Rc::try_unwrap(resource_rc)
.map_err(|_| bad_resource("TCP stream is currently in use"))?;
.map_err(|_| custom_error("Busy", "TCP stream is currently in use"))?;
let (read_half, write_half) = resource.into_inner();
let tcp_stream = read_half.reunite(write_half)?;

Expand Down Expand Up @@ -526,7 +526,6 @@ pub async fn op_net_accept_tls(
match listener.accept().try_or_cancel(&cancel_handle).await {
Ok(tuple) => tuple,
Err(err) if err.kind() == ErrorKind::Interrupted => {
// FIXME(bartlomieju): compatibility with current JS implementation.
return Err(bad_resource("Listener has been closed"));
}
Err(err) => return Err(err.into()),
Expand Down
10 changes: 5 additions & 5 deletions ext/net/raw.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use crate::io::TcpStreamResource;
use crate::ops_tls::TlsStreamResource;
use deno_core::error::bad_resource;
use deno_core::error::bad_resource_id;
use deno_core::error::custom_error;
use deno_core::error::AnyError;
use deno_core::AsyncRefCell;
use deno_core::CancelHandle;
Expand Down Expand Up @@ -70,7 +70,7 @@ impl<T: NetworkStreamListenerTrait + 'static> NetworkListenerResource<T> {
) -> Result<Option<NetworkStreamListener>, AnyError> {
if let Ok(resource_rc) = resource_table.take::<Self>(listener_rid) {
let resource = Rc::try_unwrap(resource_rc)
.map_err(|_| bad_resource("Listener is currently in use"))?;
.map_err(|_| custom_error("Busy", "Listener is currently in use"))?;
return Ok(Some(resource.listener.into_inner().into()));
}
Ok(None)
Expand Down Expand Up @@ -334,7 +334,7 @@ pub fn take_network_stream_resource(
{
// This TCP connection might be used somewhere else.
let resource = Rc::try_unwrap(resource_rc)
.map_err(|_| bad_resource("TCP stream is currently in use"))?;
.map_err(|_| custom_error("Busy", "TCP stream is currently in use"))?;
let (read_half, write_half) = resource.into_inner();
let tcp_stream = read_half.reunite(write_half)?;
return Ok(NetworkStream::Tcp(tcp_stream));
Expand All @@ -344,7 +344,7 @@ pub fn take_network_stream_resource(
{
// This TLS connection might be used somewhere else.
let resource = Rc::try_unwrap(resource_rc)
.map_err(|_| bad_resource("TLS stream is currently in use"))?;
.map_err(|_| custom_error("Busy", "TLS stream is currently in use"))?;
let (read_half, write_half) = resource.into_inner();
let tls_stream = read_half.unsplit(write_half);
return Ok(NetworkStream::Tls(tls_stream));
Expand All @@ -356,7 +356,7 @@ pub fn take_network_stream_resource(
{
// This UNIX socket might be used somewhere else.
let resource = Rc::try_unwrap(resource_rc)
.map_err(|_| bad_resource("UNIX stream is currently in use"))?;
.map_err(|_| custom_error("Busy", "Unix socket is currently in use"))?;
let (read_half, write_half) = resource.into_inner();
let unix_stream = read_half.reunite(write_half)?;
return Ok(NetworkStream::Unix(unix_stream));
Expand Down
20 changes: 10 additions & 10 deletions runtime/ops/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

use std::rc::Rc;

use deno_core::error::bad_resource;
use deno_core::error::bad_resource_id;
use deno_core::error::custom_error;
use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::OpState;
Expand All @@ -27,10 +27,10 @@ fn op_http_start(
.take::<TcpStreamResource>(tcp_stream_rid)
{
// This TCP connection might be used somewhere else. If it's the case, we cannot proceed with the
// process of starting a HTTP server on top of this TCP connection, so we just return a bad
// resource error. See also: https://github.com/denoland/deno/pull/16242
// process of starting a HTTP server on top of this TCP connection, so we just return a Busy error.
// See also: https://github.com/denoland/deno/pull/16242
let resource = Rc::try_unwrap(resource_rc)
.map_err(|_| bad_resource("TCP stream is currently in use"))?;
.map_err(|_| custom_error("Busy", "TCP stream is currently in use"))?;
let (read_half, write_half) = resource.into_inner();
let tcp_stream = read_half.reunite(write_half)?;
let addr = tcp_stream.local_addr()?;
Expand All @@ -42,10 +42,10 @@ fn op_http_start(
.take::<TlsStreamResource>(tcp_stream_rid)
{
// This TLS connection might be used somewhere else. If it's the case, we cannot proceed with the
// process of starting a HTTP server on top of this TLS connection, so we just return a bad
// resource error. See also: https://github.com/denoland/deno/pull/16242
// process of starting a HTTP server on top of this TLS connection, so we just return a Busy error.
// See also: https://github.com/denoland/deno/pull/16242
let resource = Rc::try_unwrap(resource_rc)
.map_err(|_| bad_resource("TLS stream is currently in use"))?;
.map_err(|_| custom_error("Busy", "TLS stream is currently in use"))?;
let (read_half, write_half) = resource.into_inner();
let tls_stream = read_half.unsplit(write_half);
let addr = tls_stream.local_addr()?;
Expand All @@ -58,10 +58,10 @@ fn op_http_start(
.take::<deno_net::io::UnixStreamResource>(tcp_stream_rid)
{
// This UNIX socket might be used somewhere else. If it's the case, we cannot proceed with the
// process of starting a HTTP server on top of this UNIX socket, so we just return a bad
// resource error. See also: https://github.com/denoland/deno/pull/16242
// process of starting a HTTP server on top of this UNIX socket, so we just return a Busy error.
// See also: https://github.com/denoland/deno/pull/16242
let resource = Rc::try_unwrap(resource_rc)
.map_err(|_| bad_resource("UNIX stream is currently in use"))?;
.map_err(|_| custom_error("Busy", "Unix socket is currently in use"))?;
let (read_half, write_half) = resource.into_inner();
let unix_stream = read_half.reunite(write_half)?;
let addr = unix_stream.local_addr()?;
Expand Down
15 changes: 13 additions & 2 deletions tests/integration/js_unit_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,19 @@ fn js_unit_test(test: String) {
deno = deno.arg("--unstable-worker-options");
}

// TODO(mmastrac): it would be better to just load a test CA for all tests
if test == "websocket_test" || test == "tls_sni_test" {
// Some tests require the root CA cert file to be loaded.
if test == "websocket_test" {
deno = deno.arg(format!(
"--cert={}",
util::testdata_path()
.join("tls")
.join("RootCA.pem")
.to_string_lossy()
));
};

if test == "tls_sni_test" {
// TODO(lucacasonato): fix the SNI in the certs so that this is not needed
deno = deno.arg("--unsafely-ignore-certificate-errors");
}

Expand Down
11 changes: 7 additions & 4 deletions tests/integration/node_unit_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,18 @@ fn node_unit_test(test: String) {
.arg("--no-lock")
.arg("--unstable-broadcast-channel")
.arg("--unstable-net")
// TODO(kt3k): This option is required to pass tls_test.ts,
// but this shouldn't be necessary. tls.connect currently doesn't
// pass hostname option correctly and it causes cert errors.
.arg("--unsafely-ignore-certificate-errors")
.arg("-A");

// Some tests require the root CA cert file to be loaded.
if test == "http2_test" || test == "http_test" {
deno = deno.arg("--cert=./tests/testdata/tls/RootCA.pem");
}

// Parallel tests for crypto
if test.starts_with("crypto/") {
deno = deno.arg("--parallel");
}

let mut deno = deno
.arg(
util::tests_path()
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/http_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2305,7 +2305,7 @@ Deno.test(

const buf = new Uint8Array(128);
const readPromise = serverConn.read(buf);
assertThrows(() => Deno.serveHttp(serverConn), Deno.errors.BadResource);
assertThrows(() => Deno.serveHttp(serverConn), Deno.errors.Busy);

clientConn.close();
listener.close();
Expand Down Expand Up @@ -2338,7 +2338,7 @@ Deno.test(

const buf = new Uint8Array(128);
const readPromise = serverConn.read(buf);
assertThrows(() => Deno.serveHttp(serverConn), Deno.errors.BadResource);
assertThrows(() => Deno.serveHttp(serverConn), Deno.errors.Busy);

clientConn.close();
listener.close();
Expand All @@ -2362,7 +2362,7 @@ Deno.test(

const buf = new Uint8Array(128);
const readPromise = serverConn.read(buf);
assertThrows(() => Deno.serveHttp(serverConn), Deno.errors.BadResource);
assertThrows(() => Deno.serveHttp(serverConn), Deno.errors.Busy);

clientConn.close();
listener.close();
Expand Down
4 changes: 1 addition & 3 deletions tests/unit/net_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,6 @@ Deno.test(
const listener = Deno.listen({ port: listenPort });
const p = listener.accept();
listener.close();
// TODO(piscisaureus): the error type should be `Interrupted` here, which
// gets thrown, but then ext/net catches it and rethrows `BadResource`.
await assertRejects(
() => p,
Deno.errors.BadResource,
Expand Down Expand Up @@ -168,7 +166,7 @@ Deno.test(
} else if (e.message === "Another accept task is ongoing") {
acceptErrCount++;
} else {
throw new Error("Unexpected error message");
throw e;
}
};
const p = listener.accept().catch(checkErr);
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/tls_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Deno.test(
// `Deno.startTls` cannot consume the connection.
await assertRejects(
() => Deno.startTls(clientConn, { hostname }),
Deno.errors.BadResource,
Deno.errors.Busy,
);

serverConn.close();
Expand Down
4 changes: 2 additions & 2 deletions tests/unit_node/http2_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import * as net from "node:net";
import { assert, assertEquals } from "@std/assert";
import { curlRequest } from "../unit/test_util.ts";

for (const url of ["http://127.0.0.1:4246", "https://127.0.0.1:4247"]) {
for (const url of ["http://localhost:4246", "https://localhost:4247"]) {
Deno.test(`[node/http2 client] ${url}`, {
ignore: Deno.build.os === "windows",
}, async () => {
Expand Down Expand Up @@ -155,7 +155,7 @@ Deno.test("[node/http2.createServer()]", {
res.end();
});
server.listen(0);
const port = (<net.AddressInfo> server.address()).port;
const port = (server.address() as net.AddressInfo).port;
const endpoint = `http://localhost:${port}`;

const response = await curlRequest([
Expand Down
6 changes: 4 additions & 2 deletions tests/unit_node/tls_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,12 @@ Deno.test("tls.createServer creates a TLS server", async () => {
},
);
server.listen(0, async () => {
const conn = await Deno.connectTls({
hostname: "127.0.0.1",
const tcpConn = await Deno.connect({
// deno-lint-ignore no-explicit-any
port: (server.address() as any).port,
});
const conn = await Deno.startTls(tcpConn, {
hostname: "localhost",
caCerts: [rootCaCert],
});

Expand Down