Skip to content

Commit da3b44b

Browse files
npupsholladay
andauthored
Add shortcut for using a custom catch-all handler (#17)
* 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 std@v0.56.0 * Simplify request configuration * Simplify syntax in code example Co-authored-by: Seth Holladay <me@seth-holladay.com>
1 parent dcd8bb7 commit da3b44b

File tree

8 files changed

+71
-9
lines changed

8 files changed

+71
-9
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,20 @@ const server = pogo.server();
198198

199199
Type: `object`
200200

201+
##### catchAll
202+
203+
Type: `function`
204+
205+
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)`.
206+
207+
```js
208+
pogo.server({
209+
catchAll(request, h) {
210+
return h.response('the void').code(404);
211+
}
212+
});
213+
```
214+
201215
##### certFile
202216

203217
Type: `string`\

dependencies.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import React from 'https://dev.jspm.io/react@16.12.0';
22
import ReactDOMServer from 'https://dev.jspm.io/react-dom@16.12.0/server';
3-
import * as cookie from 'https://deno.land/std@v0.53.0/http/cookie.ts';
4-
import * as http from 'https://deno.land/std@v0.53.0/http/server.ts';
5-
import { Status as status, STATUS_TEXT as statusText } from 'https://deno.land/std@v0.53.0/http/http_status.ts';
3+
import * as cookie from 'https://deno.land/std@v0.56.0/http/cookie.ts';
4+
import * as http from 'https://deno.land/std@v0.56.0/http/server.ts';
5+
import { Status as status, STATUS_TEXT as statusText } from 'https://deno.land/std@v0.56.0/http/http_status.ts';
66

77
export {
88
React,

dev-dependencies.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {
22
assert,
33
assertEquals,
44
assertStrictEq
5-
} from 'https://deno.land/std@v0.53.0/testing/asserts.ts';
5+
} from 'https://deno.land/std@v0.56.0/testing/asserts.ts';
66

77
export {
88
assert,

example/simple-server/dev-dependencies.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { assertEquals, assertStrictEq } from 'https://deno.land/std@v0.53.0/testing/asserts.ts';
1+
import { assertEquals, assertStrictEq } from 'https://deno.land/std@v0.56.0/testing/asserts.ts';
22

33
export {
44
assertEquals,

lib/request.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default class Request {
1414
route: MatchedRoute;
1515
method: string;
1616
headers: Headers;
17-
params: RequestParams
17+
params: RequestParams;
1818
referrer: string;
1919
response: Response;
2020
server: Server;

lib/server.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ export default class Server {
3535
...options
3636
};
3737
this.router = new Router();
38+
const { catchAll } = this.options;
39+
if (typeof catchAll === 'function') {
40+
this.router.all('/{catchAll*}', catchAll);
41+
}
3842
}
3943
async inject(rawRequest: http.ServerRequest): Promise<Response> {
4044
const route = this.router.lookup(rawRequest.method, getPathname(rawRequest.url));

lib/types.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ export interface MatchedRoute extends NormalizedRoute {
2525
}
2626

2727
export interface ServerOptions {
28-
hostname?: string,
29-
port: number,
28+
catchAll?: RouteHandler,
3029
certFile?: string,
31-
keyFile?: string
30+
hostname?: string,
31+
keyFile?: string,
32+
port: number
3233
}
3334

3435
type JSONStringifyable = boolean | null | number | object | string;

test/server.jsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,3 +433,46 @@ test('server.route() handler throws bang.badRequest()', async () => {
433433
status : 400
434434
}));
435435
});
436+
437+
test('server catchAll option', async () => {
438+
const server = pogo.server({
439+
catchAll(request, h) {
440+
return h.response('Custom fallback, ' + request.method).code(418);
441+
}
442+
});
443+
server.route({
444+
method : 'GET',
445+
path : '/hello',
446+
handler(request) {
447+
return 'Hi, ' + request.method;
448+
}
449+
});
450+
const getHelloResponse = await server.inject({
451+
method : 'GET',
452+
url : '/hello'
453+
});
454+
const getRootResponse = await server.inject({
455+
method : 'GET',
456+
url : '/'
457+
});
458+
const getVoidResponse = await server.inject({
459+
method : 'GET',
460+
url : '/void'
461+
});
462+
const postVoidResponse = await server.inject({
463+
method : 'POST',
464+
url : '/void'
465+
});
466+
assertStrictEq(getHelloResponse.status, 200);
467+
assertStrictEq(getHelloResponse.headers.get('content-type'), 'text/html; charset=utf-8');
468+
assertStrictEq(getHelloResponse.body, 'Hi, GET');
469+
assertStrictEq(getRootResponse.status, 418);
470+
assertStrictEq(getRootResponse.headers.get('content-type'), 'text/html; charset=utf-8');
471+
assertStrictEq(getRootResponse.body, 'Custom fallback, GET');
472+
assertStrictEq(getVoidResponse.status, 418);
473+
assertStrictEq(getVoidResponse.headers.get('content-type'), 'text/html; charset=utf-8');
474+
assertStrictEq(getVoidResponse.body, 'Custom fallback, GET');
475+
assertStrictEq(postVoidResponse.status, 418);
476+
assertStrictEq(postVoidResponse.headers.get('content-type'), 'text/html; charset=utf-8');
477+
assertStrictEq(postVoidResponse.body, 'Custom fallback, POST');
478+
});

0 commit comments

Comments
 (0)