Skip to content

Commit

Permalink
Add shortcut for using a custom catch-all handler (#17)
Browse files Browse the repository at this point in the history
* Add mechanism for using a custom catch-all handler

Implemented as an option to server instantiation.

* use existing utility to set http status code

* update mechanism of adding the catchAll handler via server options

It now internally uses the router catch-all

* Simplify route matching logic

* Update to [email protected]

* Simplify request configuration

* Simplify syntax in code example

Co-authored-by: Seth Holladay <[email protected]>
  • Loading branch information
npup and sholladay authored Jun 8, 2020
1 parent dcd8bb7 commit da3b44b
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 9 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,20 @@ const server = pogo.server();

Type: `object`

##### catchAll

Type: `function`

Optional route handler to be used as a fallback for requests that do not match any other route. This overrides the default 404 Not Found behavior built into the framework. Shortcut for `server.router.all('/{catchAll*}', catchAll)`.

```js
pogo.server({
catchAll(request, h) {
return h.response('the void').code(404);
}
});
```

##### certFile

Type: `string`\
Expand Down
6 changes: 3 additions & 3 deletions dependencies.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'https://dev.jspm.io/[email protected]';
import ReactDOMServer from 'https://dev.jspm.io/[email protected]/server';
import * as cookie from 'https://deno.land/std@v0.53.0/http/cookie.ts';
import * as http from 'https://deno.land/std@v0.53.0/http/server.ts';
import { Status as status, STATUS_TEXT as statusText } from 'https://deno.land/std@v0.53.0/http/http_status.ts';
import * as cookie from 'https://deno.land/std@v0.56.0/http/cookie.ts';
import * as http from 'https://deno.land/std@v0.56.0/http/server.ts';
import { Status as status, STATUS_TEXT as statusText } from 'https://deno.land/std@v0.56.0/http/http_status.ts';

export {
React,
Expand Down
2 changes: 1 addition & 1 deletion dev-dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
assert,
assertEquals,
assertStrictEq
} from 'https://deno.land/std@v0.53.0/testing/asserts.ts';
} from 'https://deno.land/std@v0.56.0/testing/asserts.ts';

export {
assert,
Expand Down
2 changes: 1 addition & 1 deletion example/simple-server/dev-dependencies.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assertEquals, assertStrictEq } from 'https://deno.land/std@v0.53.0/testing/asserts.ts';
import { assertEquals, assertStrictEq } from 'https://deno.land/std@v0.56.0/testing/asserts.ts';

export {
assertEquals,
Expand Down
2 changes: 1 addition & 1 deletion lib/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default class Request {
route: MatchedRoute;
method: string;
headers: Headers;
params: RequestParams
params: RequestParams;
referrer: string;
response: Response;
server: Server;
Expand Down
4 changes: 4 additions & 0 deletions lib/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export default class Server {
...options
};
this.router = new Router();
const { catchAll } = this.options;
if (typeof catchAll === 'function') {
this.router.all('/{catchAll*}', catchAll);
}
}
async inject(rawRequest: http.ServerRequest): Promise<Response> {
const route = this.router.lookup(rawRequest.method, getPathname(rawRequest.url));
Expand Down
7 changes: 4 additions & 3 deletions lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ export interface MatchedRoute extends NormalizedRoute {
}

export interface ServerOptions {
hostname?: string,
port: number,
catchAll?: RouteHandler,
certFile?: string,
keyFile?: string
hostname?: string,
keyFile?: string,
port: number
}

type JSONStringifyable = boolean | null | number | object | string;
Expand Down
43 changes: 43 additions & 0 deletions test/server.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -433,3 +433,46 @@ test('server.route() handler throws bang.badRequest()', async () => {
status : 400
}));
});

test('server catchAll option', async () => {
const server = pogo.server({
catchAll(request, h) {
return h.response('Custom fallback, ' + request.method).code(418);
}
});
server.route({
method : 'GET',
path : '/hello',
handler(request) {
return 'Hi, ' + request.method;
}
});
const getHelloResponse = await server.inject({
method : 'GET',
url : '/hello'
});
const getRootResponse = await server.inject({
method : 'GET',
url : '/'
});
const getVoidResponse = await server.inject({
method : 'GET',
url : '/void'
});
const postVoidResponse = await server.inject({
method : 'POST',
url : '/void'
});
assertStrictEq(getHelloResponse.status, 200);
assertStrictEq(getHelloResponse.headers.get('content-type'), 'text/html; charset=utf-8');
assertStrictEq(getHelloResponse.body, 'Hi, GET');
assertStrictEq(getRootResponse.status, 418);
assertStrictEq(getRootResponse.headers.get('content-type'), 'text/html; charset=utf-8');
assertStrictEq(getRootResponse.body, 'Custom fallback, GET');
assertStrictEq(getVoidResponse.status, 418);
assertStrictEq(getVoidResponse.headers.get('content-type'), 'text/html; charset=utf-8');
assertStrictEq(getVoidResponse.body, 'Custom fallback, GET');
assertStrictEq(postVoidResponse.status, 418);
assertStrictEq(postVoidResponse.headers.get('content-type'), 'text/html; charset=utf-8');
assertStrictEq(postVoidResponse.body, 'Custom fallback, POST');
});

0 comments on commit da3b44b

Please sign in to comment.