Skip to content

Commit 14ee93e

Browse files
committed
Throw NotFoundError during render()
Add renderNotFound() hook to render custom UI during NotFoundError.
1 parent 1be33c1 commit 14ee93e

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

index.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@
88
var React = require('react');
99
var invariant = require('react/lib/invariant');
1010
var createRouter = require('./router');
11-
var NotFoundError = require('./not-found-error');
1211
var utils = require('./utils');
1312
var request = require('./request');
13+
var NotFoundError = require('./not-found-error');
1414

1515
var ControllerInterface = {
1616

1717
getInitialState: function() {
1818
var req = this.props.request;
19+
var page = this.createPageForRequest(req);
1920
return {
2021
request: req,
21-
page: this.createPageForRequest(req)
22+
page: page
2223
};
2324
},
2425

@@ -29,7 +30,13 @@ var ControllerInterface = {
2930
* ReactCompositeComponent policy which disallows render() method overrides.
3031
*/
3132
defaultRender: function() {
32-
return React.DOM.div(null, this.state.page);
33+
if (this.state.page !== null) {
34+
return React.DOM.div(null, this.state.page);
35+
} else if (typeof this.renderNotFound === 'function') {
36+
return this.renderNotFound();
37+
} else {
38+
throw new NotFoundError(this.state.request.path);
39+
}
3340
},
3441

3542
componentDidMount: function() {
@@ -50,7 +57,7 @@ var ControllerInterface = {
5057
var match = this.router.match(req.path);
5158

5259
if (!match) {
53-
throw new NotFoundError(req.path);
60+
return null;
5461
}
5562

5663
return match.handler(utils.extend({request: req}, match.params));
@@ -70,9 +77,11 @@ var ControllerInterface = {
7077
if (request.isEqual(this.state.request, req))
7178
return;
7279

80+
var page = this.createPageForRequest(req);
81+
7382
this.setState({
7483
request: req,
75-
page: this.createPageForRequest(req)
84+
page: page
7685
}, cb);
7786
},
7887

specs/client.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ describe('react-app-controller on client', function() {
121121
assert.equal(controller.state.request.path, '/');
122122

123123
controller.navigate('/about', function() {
124+
assert.ok(!err);
124125
assert.ok(!document.querySelector('.MainPage'));
125126
assert.ok(document.querySelector('.AboutPage'));
126127
assert.ok(controller.state.page);
@@ -139,6 +140,22 @@ describe('react-app-controller on client', function() {
139140
});
140141
});
141142

143+
it('allows rendering custom UI on NotFoundError', function(done) {
144+
controller = createController({
145+
routes: {},
146+
renderNotFound: function() {
147+
return React.DOM.div({className: 'NotFound'}, '404');
148+
}
149+
});
150+
151+
controller.render(root, '/about', function(err, controller) {
152+
assert.ok(!err, err);
153+
assert.ok(document.querySelector('.NotFound'));
154+
assert.ok(controller.state.page === null);
155+
done();
156+
});
157+
});
158+
142159
});
143160

144161
});

specs/server.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,19 @@ describe('react-app-controller on server', function() {
4343
done();
4444
});
4545
});
46+
47+
it('allows rendering custom UI on NotFoundError', function(done) {
48+
controller = createController({
49+
routes: {},
50+
renderNotFound: function() {
51+
return React.DOM.div(null, '404');
52+
}
53+
});
54+
55+
controller.renderToString('/about', function(err, markup) {
56+
assert.ok(!err, err);
57+
assert.ok(/404/.exec(markup.markup));
58+
done();
59+
});
60+
});
4661
});

0 commit comments

Comments
 (0)