From d050b491b10fe37b4461b37c56028a14c8674c95 Mon Sep 17 00:00:00 2001 From: Inteon <42113979+inteon@users.noreply.github.com> Date: Thu, 8 Apr 2021 18:04:02 +0200 Subject: [PATCH] fix(core): error handling in examples (#9867) --- cli/bench/deno_tcp.ts | 15 +++++++----- cli/bench/deno_tcp_proxy.ts | 14 ++++++----- cli/bench/http.rs | 2 ++ cli/bench/node_tcp_promise.js | 25 -------------------- cli/tests/unit/dispatch_bin_test.ts | 26 +++++++++++++++++++++ core/examples/http_bench_bin_ops.js | 35 +++++++++++----------------- core/examples/http_bench_json_ops.js | 24 +++++++++---------- runtime/js/12_io.js | 20 ++-------------- 8 files changed, 72 insertions(+), 89 deletions(-) delete mode 100644 cli/bench/node_tcp_promise.js diff --git a/cli/bench/deno_tcp.ts b/cli/bench/deno_tcp.ts index e6ee4e239b..2216beab5a 100644 --- a/cli/bench/deno_tcp.ts +++ b/cli/bench/deno_tcp.ts @@ -13,15 +13,18 @@ async function handle(conn: Deno.Conn): Promise { const buffer = new Uint8Array(1024); try { while (true) { - const r = await conn.read(buffer); - if (r === null) { - break; - } + await conn.read(buffer); await conn.write(response); } - } finally { - conn.close(); + } catch (e) { + if ( + !(e instanceof Deno.errors.BrokenPipe) && + !(e instanceof Deno.errors.ConnectionReset) + ) { + throw e; + } } + conn.close(); } console.log("Listening on", addr); diff --git a/cli/bench/deno_tcp_proxy.ts b/cli/bench/deno_tcp_proxy.ts index 1a424cee52..bab8eac192 100644 --- a/cli/bench/deno_tcp_proxy.ts +++ b/cli/bench/deno_tcp_proxy.ts @@ -15,14 +15,16 @@ async function handle(conn: Deno.Conn): Promise { }); try { await Promise.all([Deno.copy(conn, origin), Deno.copy(origin, conn)]); - } catch (err) { - if (err.message !== "read error" && err.message !== "write error") { - throw err; + } catch (e) { + if ( + !(e instanceof Deno.errors.BrokenPipe) && + !(e instanceof Deno.errors.ConnectionReset) + ) { + throw e; } - } finally { - conn.close(); - origin.close(); } + conn.close(); + origin.close(); } console.log(`Proxy listening on http://${addr}/`); diff --git a/cli/bench/http.rs b/cli/bench/http.rs index f954223a0a..952f3f19b5 100644 --- a/cli/bench/http.rs +++ b/cli/bench/http.rs @@ -107,6 +107,8 @@ fn run( println!("{}", wrk_cmd.join(" ")); let output = test_util::run_collect(wrk_cmd, None, None, None, true).0; + std::thread::sleep(Duration::from_secs(1)); // wait to capture failure. TODO racy. + println!("{}", output); assert!( server.try_wait()?.map_or(true, |s| s.success()), diff --git a/cli/bench/node_tcp_promise.js b/cli/bench/node_tcp_promise.js deleted file mode 100644 index 6f0b810e5a..0000000000 --- a/cli/bench/node_tcp_promise.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -// Note: this is a keep-alive server. -const { Server } = require("net"); -const port = process.argv[2] || "4544"; -console.log("port", port); - -const response = Buffer.from( - "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World\n", -); - -function write(socket, buffer) { - const p = new Promise((resolve, _) => { - socket.write(buffer, resolve); - }); - return Promise.resolve(p); -} - -Server(async (socket) => { - socket.on("error", (_) => { - socket.destroy(); - }); - for await (const _ of socket) { - await write(socket, response); - } -}).listen(port); diff --git a/cli/tests/unit/dispatch_bin_test.ts b/cli/tests/unit/dispatch_bin_test.ts index 83053461d4..ca18646219 100644 --- a/cli/tests/unit/dispatch_bin_test.ts +++ b/cli/tests/unit/dispatch_bin_test.ts @@ -32,3 +32,29 @@ declare global { var core: any; // eslint-disable-line no-var } } + +unitTest(async function binOpsAsyncBadResource(): Promise { + try { + const nonExistingRid = 9999; + await Deno.core.binOpAsync( + "op_read_async", + nonExistingRid, + new Uint8Array(0), + ); + } catch (e) { + if (!(e instanceof Deno.errors.BadResource)) { + throw e; + } + } +}); + +unitTest(function binOpsSyncBadResource(): void { + try { + const nonExistingRid = 9999; + Deno.core.binOpSync("op_read_sync", nonExistingRid, new Uint8Array(0)); + } catch (e) { + if (!(e instanceof Deno.errors.BadResource)) { + throw e; + } + } +}); diff --git a/core/examples/http_bench_bin_ops.js b/core/examples/http_bench_bin_ops.js index cf5e275b10..c3128dbb20 100644 --- a/core/examples/http_bench_bin_ops.js +++ b/core/examples/http_bench_bin_ops.js @@ -9,19 +9,14 @@ const responseBuf = new Uint8Array( .map((c) => c.charCodeAt(0)), ); -// This buffer exists purely to avoid trigerring the bin-op buf assert -// in practice all deno bin ops accept buffers, this bench is an exception -// TODO(@AaronO): remove once we drop variadic BufVec compat -const nopBuffer = new Uint8Array(); - /** Listens on 0.0.0.0:4500, returns rid. */ function listen() { - return Deno.core.binOpSync("listen", 0, nopBuffer); + return Deno.core.binOpSync("listen", 0); } /** Accepts a connection, returns rid. */ function accept(rid) { - return Deno.core.binOpAsync("accept", rid, nopBuffer); + return Deno.core.binOpAsync("accept", rid); } /** @@ -38,19 +33,21 @@ function write(rid, data) { } function close(rid) { - Deno.core.binOpSync("close", rid, nopBuffer); + Deno.core.binOpSync("close", rid); } async function serve(rid) { - while (true) { - const nread = await read(rid, requestBuf); - if (nread <= 0) { - break; + try { + while (true) { + await read(rid, requestBuf); + await write(rid, responseBuf); } - - const nwritten = await write(rid, responseBuf); - if (nwritten < 0) { - break; + } catch (e) { + if ( + !e.message.includes("Broken pipe") && + !e.message.includes("Connection reset by peer") + ) { + throw e; } } close(rid); @@ -65,12 +62,8 @@ async function main() { `http_bench_bin_ops listening on http://127.0.0.1:4544/\n`, ); - for (;;) { + while (true) { const rid = await accept(listenerRid); - if (rid < 0) { - Deno.core.print(`accept error ${rid}`); - return; - } serve(rid); } } diff --git a/core/examples/http_bench_json_ops.js b/core/examples/http_bench_json_ops.js index 791fcc4998..f8ac05353d 100644 --- a/core/examples/http_bench_json_ops.js +++ b/core/examples/http_bench_json_ops.js @@ -37,15 +37,17 @@ function close(rid) { } async function serve(rid) { - while (true) { - const nread = await read(rid, requestBuf); - if (nread <= 0) { - break; + try { + while (true) { + await read(rid, requestBuf); + await write(rid, responseBuf); } - - const nwritten = await write(rid, responseBuf); - if (nwritten < 0) { - break; + } catch (e) { + if ( + !e.message.includes("Broken pipe") && + !e.message.includes("Connection reset by peer") + ) { + throw e; } } close(rid); @@ -58,12 +60,8 @@ async function main() { const listenerRid = listen(); Deno.core.print(`http_bench_json_ops listening on http://127.0.0.1:4544/\n`); - for (;;) { + while (true) { const rid = await accept(listenerRid); - if (rid < 0) { - Deno.core.print(`accept error ${rid}`); - return; - } serve(rid); } } diff --git a/runtime/js/12_io.js b/runtime/js/12_io.js index aa153e9fd6..a6b6aeebdb 100644 --- a/runtime/js/12_io.js +++ b/runtime/js/12_io.js @@ -82,9 +82,6 @@ } const nread = core.binOpSync("op_read_sync", rid, buffer); - if (nread < 0) { - throw new Error("read error"); - } return nread === 0 ? null : nread; } @@ -98,29 +95,16 @@ } const nread = await core.binOpAsync("op_read_async", rid, buffer); - if (nread < 0) { - throw new Error("read error"); - } return nread === 0 ? null : nread; } function writeSync(rid, data) { - const result = core.binOpSync("op_write_sync", rid, data); - if (result < 0) { - throw new Error("write error"); - } - - return result; + return core.binOpSync("op_write_sync", rid, data); } async function write(rid, data) { - const result = await core.binOpAsync("op_write_async", rid, data); - if (result < 0) { - throw new Error("write error"); - } - - return result; + return await core.binOpAsync("op_write_async", rid, data); } const READ_PER_ITER = 32 * 1024;