
Deno Oak application events
Introduction
The very popular middleware framework for Deno is Oak. Oak is a middleware framework for Deno’s native HTTP server, Deno Deploy and Node.js 16.5 and later. It also includes a middleware router.
This middleware framework is inspired by Koa and middleware router inspired by @koa/router.
In addition to supporting middlewares, automatic body processing, router, etc. the Oak application also raises two useful events to the application:
- Error event
- Listen event
These events are mostly useful for logging, statistics, etc. In this article, we’ll learn about these two commonly used events.
Listen event
Consider the following simple hello world Oak application:
// app.tsimport { Application } from "https://deno.land/x/oak/mod.ts";const port = 8080;const app = new Application();app.use((ctx) => ctx.response.body = "Hello world!");app.listen({ port });
This application can be started with deno run command:
~: deno run --allow-net=:8080 app.ts
There is no log like ‘Server listening on <port>’. Such a log could be useful for debugging, statistics, etc.
To get such a log, we need to capture the ‘listen’ event raised by the Application object. The capturing is done via web standard API: addEventListener.
Here is the updated code:
// app.tsimport { Application } from "https://deno.land/x/oak/mod.ts";const port = 8080;const app = new Application();app.use((ctx) => ctx.response.body = "Hello world!");app.addEventListener(
"listen",
() => console.log(`Server listening on ${port}`),
);app.listen({ port });
The listen log would only be produced when Oak application is able to start the listener successfully.
~: deno run --allow-net=:8080 app.ts
Server listening on 8080
Error Event
To get notified for all kind of errors, an error event can be deployed using the same web standard addEventListener API. The error event is only useful for logging purposes because the Oak framework captures all errors anyway.
Consider the following application that throws an error:
// app.tsimport { Application } from "https://deno.land/x/oak/mod.ts";const port = 8080;const app = new Application();app.use((ctx) => {
throw new Error("An error for you!");
});app.addEventListener(
"listen",
() => console.log(`Server listening on ${port}`),
);app.listen({ port });
The application is always going to raise an error. Let’s test it out:
~: curl http://localhost:8080
Internal Server Error~: deno run --allow-net=:8080 app.ts
Server listening on 8080
[uncaught application error]: Error - An error for you!request: { url: "http://localhost:8080/", method: "GET", hasBody: false }
response: { status: 404, type: undefined, hasBody: false, writable: true }at file:///Users/mayankc/Work/source/denoExamples/app.ts:8:9
at dispatch (https://deno.land/x/oak@v10.5.1/middleware.ts:41:13)
at composedMiddleware (https://deno.land/x/oak@v10.5.1/middleware.ts:44:12)
at Application.#handleRequest (https://deno.land/x/oak@v10.5.1/application.ts:389:34)
at Application.listen (https://deno.land/x/oak@v10.5.1/application.ts:559:28)
The Oak’s error handler handles the error, prints the error, and sends a 500 response back to the caller.
Let’s add an error event handler that would produce a custom log line:
// app.tsimport { Application } from "https://deno.land/x/oak/mod.ts";const port = 8080;const app = new Application();app.use((ctx) => {
throw new Error("An error for you!");
});app.addEventListener(
"error",
(e) => console.log(`Caught error: ${e.message}`),
);app.addEventListener(
"listen",
() => console.log(`Server listening on ${port}`),
);app.listen({ port });
The Oak framework would still handle the error, print the error, and send a 500 back to the caller. Additionally, the error event handler would print a custom log message.
~: curl http://localhost:8080
Internal Server Error~: deno run --allow-net=:8080 app.ts
Server listening on 8080
[uncaught application error]: Error - An error for you!request: { url: "http://localhost:8080/", method: "GET", hasBody: false }
response: { status: 404, type: undefined, hasBody: false, writable: true }at file:///Users/mayankc/Work/source/denoExamples/app.ts:8:9
at dispatch (https://deno.land/x/oak@v10.5.1/middleware.ts:41:13)
at composedMiddleware (https://deno.land/x/oak@v10.5.1/middleware.ts:44:12)
at Application.#handleRequest (https://deno.land/x/oak@v10.5.1/application.ts:389:34)
at Application.listen (https://deno.land/x/oak@v10.5.1/application.ts:559:28)
Caught error: An error for you!
Of course, the error event handler shouldn’t just log the error again. It is more useful for recording statistics, etc.
This story is a part of the exclusive medium publication on Deno: Deno World.