Skip to content

Commit e980cef

Browse files
committed
change error handling and some other api improvements
1 parent ed274a1 commit e980cef

File tree

4 files changed

+55
-53
lines changed

4 files changed

+55
-53
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@
2727
},
2828
"dependencies": {
2929
"react": "15.x.x",
30-
"router-async": "0.2.x"
30+
"router-async": "0.4.x"
3131
}
3232
}

src/browser-router.tsx

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export default class BrowserRouter extends Router {
1010
this.history = props.history;
1111
}
1212
static async init(opts: initParams): Promise<initResult> {
13+
opts.path = opts.history.location.pathname + opts.history.location.search + opts.history.location.hash;
1314
const result = await super.init(opts);
1415
return {
1516
...result,
@@ -25,19 +26,15 @@ export default class BrowserRouter extends Router {
2526
};
2627
}
2728
async navigate(path, ctx = new Context()) {
28-
try {
29-
const { redirect } = await this.router.match({ path, ctx });
29+
const { redirect, error } = await this.router.match({ path, ctx });
30+
if (error === null) {
3031
if (redirect) {
3132
this.history.push(redirect);
3233
} else {
3334
this.history.push(path);
3435
}
35-
} catch (error) {
36+
} else {
3637
this.history.push(path);
37-
if (!this.props.errorHandler) {
38-
console.error('Match Error', path, error);
39-
throw error;
40-
}
4138
}
4239
}
4340
async push(path) {
@@ -62,29 +59,24 @@ export default class BrowserRouter extends Router {
6259
}
6360
private _locationChanged = async ({ pathname, hash, search }) => {
6461
const path = pathname + search + hash;
65-
try {
66-
const { location, route, status, params, redirect, result, ctx } = await this.router.run({ path });
67-
const props = {
68-
router: {
69-
path,
70-
location,
71-
route,
72-
status,
73-
params,
74-
redirect,
75-
ctx
76-
}
77-
};
78-
const renderCallback = Router.makeCallback(this.router, { path, location, route, status, params, redirect, result, ctx });
79-
this.changeComponent({ Component: result, componentProps: props, path, location, renderCallback });
80-
} catch (error) {
81-
if (this.props.errorHandler) {
82-
this.props.errorHandler(error, this);
83-
} else {
84-
console.error('Resolve Error', location, error);
85-
throw error;
86-
}
62+
let { location, route, status, params, redirect, result, ctx, error } = await this.router.run({ path });
63+
if (error !== null) {
64+
result = Router.getErrorComponent(error, this.errors);
8765
}
66+
const props = {
67+
router: {
68+
path,
69+
location,
70+
route,
71+
status,
72+
params,
73+
redirect,
74+
ctx,
75+
error
76+
}
77+
};
78+
const renderCallback = Router.makeCallback(this.router, { path, location, route, status, params, redirect, result, ctx });
79+
this.changeComponent({ Component: result, componentProps: props, path, location, error, renderCallback });
8880
};
8981
componentDidMount() {
9082
this.unlistenHistroy = this.history.listen(this._locationChanged)

src/router.tsx

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ export interface initParams {
3333
routes: Array<Route>,
3434
hooks: any,
3535
history?: any,
36-
silent?: boolean,
37-
ctx: any
36+
ctx: any,
37+
errors: any
3838
}
3939
export interface initResult {
4040
Router?: any,
@@ -48,10 +48,11 @@ export interface initResult {
4848

4949
export default class Router extends React.Component<Props, State> {
5050
router: any;
51+
errors: any;
5152
path: string;
5253
location: any;
5354
private subscriber: any;
54-
constructor({ Component, componentProps, router, path, location }) {
55+
constructor({ Component, componentProps, router, path, location, errors }) {
5556
super();
5657
this.state = {
5758
Component,
@@ -61,18 +62,22 @@ export default class Router extends React.Component<Props, State> {
6162
};
6263

6364
this.router = router;
65+
this.errors = errors;
6466
this.subscriber = null;
6567
}
6668
static async init(opts: initParams): Promise<initResult> {
67-
const { path, routes, hooks, history = null, silent = false, ctx = new Context() } = opts;
69+
const { path, routes, hooks, history = null, ctx = new Context(), errors } = opts;
6870
let plainRoutes;
6971
if ((Array.isArray(routes) && React.isValidElement(routes[0])) || React.isValidElement(routes)) {
7072
plainRoutes = Router.buildRoutes(routes);
7173
} else {
7274
plainRoutes = routes;
7375
}
7476
const router = new RouterAsync({ routes: plainRoutes, hooks });
75-
const { location, route, status, params, redirect, result } = await router.run({ path, ctx, silent });
77+
let { location, route, status, params, redirect, result, error } = await router.run({ path, ctx });
78+
if (error !== null) {
79+
result = Router.getErrorComponent(error, errors);
80+
}
7681
const componentProps = {
7782
router: {
7883
path,
@@ -81,7 +86,8 @@ export default class Router extends React.Component<Props, State> {
8186
status,
8287
params,
8388
redirect,
84-
ctx
89+
ctx,
90+
error
8591
}
8692
};
8793

@@ -95,10 +101,12 @@ export default class Router extends React.Component<Props, State> {
95101
router,
96102
path,
97103
location,
98-
history
104+
history,
105+
errors
99106
},
100107
componentProps,
101-
callback: this.makeCallback(router, { path, location, route, status, params, redirect, result, ctx })
108+
callback: this.makeCallback(router, { path, location, route, status, params, redirect, result, ctx }),
109+
error
102110
}
103111
}
104112
static buildRoutes(routes) {
@@ -124,10 +132,22 @@ export default class Router extends React.Component<Props, State> {
124132
subscribe(callback: Function) {
125133
this.subscriber = callback.bind(this);
126134
}
127-
changeComponent({ Component, componentProps, path, location, renderCallback }) {
135+
static getErrorComponent(error, errors) {
136+
if (error.status in errors) {
137+
return errors[error.status];
138+
}
139+
if ('*' in errors) {
140+
return errors['*'];
141+
}
142+
return 'Internal error';
143+
}
144+
changeComponent({ Component, componentProps, path, location, error, renderCallback }) {
128145
if (this.subscriber) {
129-
this.subscriber({ Component, componentProps, path, location, renderCallback });
146+
this.subscriber({ Component, componentProps, path, location, error, renderCallback });
130147
} else {
148+
if (error !== null) {
149+
Component = Router.getErrorComponent(error, this.errors);
150+
}
131151
this.setState({
132152
path,
133153
location,
@@ -136,16 +156,6 @@ export default class Router extends React.Component<Props, State> {
136156
}, renderCallback);
137157
}
138158
}
139-
replaceComponent(Component, componentProps) {
140-
if (this.subscriber) {
141-
this.subscriber({ Component, componentProps, path: this.state.path, location: this.state.location })
142-
} else {
143-
this.setState({
144-
Component,
145-
componentProps
146-
});
147-
}
148-
}
149159
getState() {
150160
return this.state;
151161
}

yarn.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ [email protected]:
9494
loose-envify "^1.1.0"
9595
object-assign "^4.1.0"
9696

97-
router-async@0.2.x:
98-
version "0.2.3"
99-
resolved "https://registry.yarnpkg.com/router-async/-/router-async-0.2.3.tgz#60606e65bb8f303da268ef31c5038b286ad0eb4e"
97+
router-async@0.4.x:
98+
version "0.4.0"
99+
resolved "https://registry.yarnpkg.com/router-async/-/router-async-0.4.0.tgz#baa2b1c99af6deff141ff24acd5e7f02e3c757d1"
100100
dependencies:
101101
path-to-regexp "^1.6.0"
102102
query-string "^4.2.3"

0 commit comments

Comments
 (0)