D
Deno

help

Deno.serve AbortController onError. How?

BBairdy8/6/2023
When I run my new Deno.serve() updated implementation I get a type error. Perhaps I'm doing it wrong. Maybe it is the way I am trying to use the Abort Controller or maybe the onError handler must always return something?
// You can stop the server with an AbortSignal.
// The abort signal needs to be passed as the signal option in the options bag.
const ac = new AbortController();

const server = Deno.serve({
// The port to listen on.
port: config.http.server.port,
// A literal IP address or host name that can be resolved to an IP address.
hostname: "0.0.0.0",
// An AbortSignal to close the server and all connections.
signal: ac.signal,
// The callback which is called when the server starts listening.
onListen({ port, hostname }) {
// console.log(`Server started at http://${hostname}:${port}`);
console.log(
`%cApplication..... fsrv v2.0 - A Deno HTTP Server
Deno v${Deno.version.deno} : Typescript v${Deno.version.typescript} : V8 v${Deno.version.v8}
Gateway URL..... http://${hostname}:${port}
Server Root..... ${pathJoin(CWD, config.http.server.www)}
Internal Pages.. ${pathJoin(CWD, config.http.server.internal)}
Site Root....... ${pathJoin(CWD, config.http.server.public)}`,
"color: #7986cb",
);
},
// The handler to invoke when route handlers throw an error.
onError(error) {
console.error(error);
log("HTTP 500");

// FATAL ERROR!

// The server aborts when the abort signal is sent to the abort controller.
console.log("Closing server...");
ac.abort();
// To wait for the server to close, await the promise returned from the Deno.serve API.
server.finished.then(() => console.log("Server closed"));

},
}, handler);
// You can stop the server with an AbortSignal.
// The abort signal needs to be passed as the signal option in the options bag.
const ac = new AbortController();

const server = Deno.serve({
// The port to listen on.
port: config.http.server.port,
// A literal IP address or host name that can be resolved to an IP address.
hostname: "0.0.0.0",
// An AbortSignal to close the server and all connections.
signal: ac.signal,
// The callback which is called when the server starts listening.
onListen({ port, hostname }) {
// console.log(`Server started at http://${hostname}:${port}`);
console.log(
`%cApplication..... fsrv v2.0 - A Deno HTTP Server
Deno v${Deno.version.deno} : Typescript v${Deno.version.typescript} : V8 v${Deno.version.v8}
Gateway URL..... http://${hostname}:${port}
Server Root..... ${pathJoin(CWD, config.http.server.www)}
Internal Pages.. ${pathJoin(CWD, config.http.server.internal)}
Site Root....... ${pathJoin(CWD, config.http.server.public)}`,
"color: #7986cb",
);
},
// The handler to invoke when route handlers throw an error.
onError(error) {
console.error(error);
log("HTTP 500");

// FATAL ERROR!

// The server aborts when the abort signal is sent to the abort controller.
console.log("Closing server...");
ac.abort();
// To wait for the server to close, await the promise returned from the Deno.serve API.
server.finished.then(() => console.log("Server closed"));

},
}, handler);
I get the following error:
error: TS2322 [ERROR]: Type '(error: unknown) => void' is not assignable to type '(error: unknown) => Response | Promise<Response>'.
Type 'void' is not assignable to type 'Response | Promise<Response>'.
onError(error) {
error: TS2322 [ERROR]: Type '(error: unknown) => void' is not assignable to type '(error: unknown) => Response | Promise<Response>'.
Type 'void' is not assignable to type 'Response | Promise<Response>'.
onError(error) {
MMrKleeblatt8/6/2023
That's because onError needs a return value. Although never called because of the ac.abort() call, just add
return new Response("never");
return new Response("never");
at the end of the onError function.
Gguest2713148/6/2023
Technically a reason should be passed to AbortController.abort('Stream aborted') so that reason can be propagated to abort() methods and/or catch()/catch (e) {}.
BBairdy8/6/2023
Thank you both for such simple solutions. I now have 2 working example scenarios. Scenario #1 * Once started, the server runs regardless of encountering route handler errors. * onError, a warning HTTP 500 response is still returned to the client. * There is no Abort Controller.
Deno.serve({
// The port to listen on.
port: config.http.server.port,
// A literal IP address or host name that can be resolved to an IP address.
hostname: "0.0.0.0",
// The callback which is called when the server starts listening.
onListen({ port, hostname }) {
console.log(
`%cApplication..... fsrv v2.0 - A Deno HTTP Server
Deno v${Deno.version.deno} : Typescript v${Deno.version.typescript} : V8 v${Deno.version.v8}
Permissions: --allow-sys --allow-read --allow-net
Gateway URL..... http://${hostname}:${port}
Server Root..... ${config.http.server.www}
Internal Pages.. ${config.http.server.internal}
Site Root....... ${config.http.server.public}\n\n`,
"color: #7986cb",
);
},
// The handler to invoke when route handlers throw an error.
onError(error: unknown) {
console.error(error);
console.log("HTTP 500");

// WARNING!

/**
* onError returns HTTP response.
* Server proceeds to next request.
*
*/
return serverResponse(
"HTTP 500: Internal Server Error",
500,
"text/plain",
);

},
}, handler); // <-- The handler goes here
Deno.serve({
// The port to listen on.
port: config.http.server.port,
// A literal IP address or host name that can be resolved to an IP address.
hostname: "0.0.0.0",
// The callback which is called when the server starts listening.
onListen({ port, hostname }) {
console.log(
`%cApplication..... fsrv v2.0 - A Deno HTTP Server
Deno v${Deno.version.deno} : Typescript v${Deno.version.typescript} : V8 v${Deno.version.v8}
Permissions: --allow-sys --allow-read --allow-net
Gateway URL..... http://${hostname}:${port}
Server Root..... ${config.http.server.www}
Internal Pages.. ${config.http.server.internal}
Site Root....... ${config.http.server.public}\n\n`,
"color: #7986cb",
);
},
// The handler to invoke when route handlers throw an error.
onError(error: unknown) {
console.error(error);
console.log("HTTP 500");

// WARNING!

/**
* onError returns HTTP response.
* Server proceeds to next request.
*
*/
return serverResponse(
"HTTP 500: Internal Server Error",
500,
"text/plain",
);

},
}, handler); // <-- The handler goes here
Scenario #2 * Once started, the server runs until the first error is thrown by the route handlers. * onError, the abort signal is sent to the AbortController. * The abort signal needs to be passed as the signal option in the options bag.
const ac = new AbortController();

const server = Deno.serve({
// The port to listen on.
port: config.http.server.port,
// A literal IP address or host name that can be resolved to an IP address.
hostname: "0.0.0.0",
// An AbortSignal to close the server and all connections.
signal: ac.signal,
// The callback which is called when the server starts listening.
onListen({ port, hostname }) {
// console.log(`Server started at http://${hostname}:${port}`);
console.log(
`%cApplication..... fsrv v2.0 - A Deno HTTP Server
Deno v${Deno.version.deno} : Typescript v${Deno.version.typescript} : V8 v${Deno.version.v8}
Gateway URL..... http://${hostname}:${port}
Server Root..... ${config.http.server.www}
Internal Pages.. ${config.http.server.internal}
Site Root....... ${config.http.server.public}`,
"color: #7986cb",
);
},
// The handler to invoke when route handlers throw an error.
onError(error: unknown) {
console.error(error);
log("HTTP 500");

// FATAL ERROR!

// The server aborts when the abort signal is sent to the abort controller.
console.log("Closing server...");

// Send the abort signal!
ac.abort("Stream aborted");

// To wait for the server to close, await the promise returned from the Deno.serve API.
server.finished.then(() => console.log("Server closed"));

/**
* onError needs a return value or error Type 'void' is not assignable
* to type 'Response | Promise<Response>' occurs.
*
* return here is NEVER reached because of the ac.abort() call that preceeds it.
*
*/
return new Response("Stream aborted");

},
}, handler); // <-- The handler goes here
const ac = new AbortController();

const server = Deno.serve({
// The port to listen on.
port: config.http.server.port,
// A literal IP address or host name that can be resolved to an IP address.
hostname: "0.0.0.0",
// An AbortSignal to close the server and all connections.
signal: ac.signal,
// The callback which is called when the server starts listening.
onListen({ port, hostname }) {
// console.log(`Server started at http://${hostname}:${port}`);
console.log(
`%cApplication..... fsrv v2.0 - A Deno HTTP Server
Deno v${Deno.version.deno} : Typescript v${Deno.version.typescript} : V8 v${Deno.version.v8}
Gateway URL..... http://${hostname}:${port}
Server Root..... ${config.http.server.www}
Internal Pages.. ${config.http.server.internal}
Site Root....... ${config.http.server.public}`,
"color: #7986cb",
);
},
// The handler to invoke when route handlers throw an error.
onError(error: unknown) {
console.error(error);
log("HTTP 500");

// FATAL ERROR!

// The server aborts when the abort signal is sent to the abort controller.
console.log("Closing server...");

// Send the abort signal!
ac.abort("Stream aborted");

// To wait for the server to close, await the promise returned from the Deno.serve API.
server.finished.then(() => console.log("Server closed"));

/**
* onError needs a return value or error Type 'void' is not assignable
* to type 'Response | Promise<Response>' occurs.
*
* return here is NEVER reached because of the ac.abort() call that preceeds it.
*
*/
return new Response("Stream aborted");

},
}, handler); // <-- The handler goes here

Looking for more? Join the community!

Recommended Posts
LocalStorage OverrideI'm using a library (@supabase/supabase-js), and I'm compiling my Deno app into an executable, howevBad implementation of X25519?I can't generate a shared secret with the current implementation of X25519 ```ts const alice = awaiResize image/convert on uploadHi there, I want to store images uploaded in webp format at 200x200px. Has anyone done something likI cant import the Zustand module from deno.I leave a photo of what it shows when I put the url to the import map. And try to cache the module.Sub hosting SAAS appWhat technologies are behind the Deno Deploy feature, where you can set up your own domain name? I What should my entry point be on Deno Deploy?Only ever used firebase before. I'm getting a 502 bad gateway error when deploying my website.tsParticles & DenoHi, I’m working on a personal project with Deno & Lume. I’m trying to use tsParticles with preact. Looking for a library to pretty print </br>, <a>, etc tagsAs that title says, I'm looking for a library that can pretty print a string containing the mentioneImporting `puppeteer-cluster` from esm.sh causes `does not provide an export named 'default'` errorWhen importing `https://esm.sh/puppeteer-cluster@0.23.0` I get the following error: ``` error: UncauDeno linting not workingHello everyone, I enabled deno for a subpath in my project (`./supabase`) but unfortunately I'm not deno_pythonI'm trying to use Python with Deno with https://deno.land/x/python@0.2.7 What should I do to enable Deno VS Code plugin too aggressive in auto-completionI'm new to Deno and learning through some tutorials. I'm using VS Code and have the Deno plugin enab