Skip to content

Commit 7d03c5b

Browse files
authored
Merge pull request #21 from opentripplanner/dev
New release
2 parents b0370f0 + c5fbfce commit 7d03c5b

File tree

8 files changed

+80
-34
lines changed

8 files changed

+80
-34
lines changed

Diff for: __tests__/actions/__snapshots__/api.js.snap

+17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`actions > api > planTrip should gracefully handle bad response 1`] = `
4+
Array [
5+
Array [
6+
Object {
7+
"type": "PLAN_REQUEST",
8+
},
9+
],
10+
Array [
11+
Object {
12+
"error": true,
13+
"payload": [Error: Received error from server],
14+
"type": "PLAN_ERROR",
15+
},
16+
],
17+
]
18+
`;
19+
320
exports[`actions > api > planTrip should make a query to OTP with customOtpQueryBuilder in state config 1`] = `"/api/plan?from=here&to=there"`;
421

522
exports[`actions > api > planTrip should make a query to OTP with customOtpQueryBuilder in state config 2`] = `

Diff for: __tests__/actions/api.js

+20
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,25 @@ describe('actions > api', () => {
8787
expect(mockDispatch.mock.calls).toMatchSnapshot()
8888
})
8989
})
90+
91+
it('should gracefully handle bad response', async () => {
92+
const planTripAction = planTrip()
93+
94+
nock('http://mock-host.com')
95+
.get(/api\/plan/)
96+
.reply(500, {
97+
fake: 'response'
98+
})
99+
100+
const mockDispatch = jest.fn()
101+
planTripAction(mockDispatch, () => {
102+
return defaultState
103+
})
104+
105+
// wait for request to complete
106+
await timeoutPromise(100)
107+
108+
expect(mockDispatch.mock.calls).toMatchSnapshot()
109+
})
90110
})
91111
})

Diff for: example.css

-9
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,3 @@
1818
margin: 0px;
1919
padding: 0px;
2020
}
21-
22-
button.header, button.step, .intermediate-stops button {
23-
background: inherit;
24-
color: inherit;
25-
border: 0;
26-
text-align: inherit;
27-
text-decoration: none;
28-
width: 100%;
29-
}

Diff for: lib/actions/api.js

+16-10
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ if (typeof (fetch) === 'undefined') {
1010

1111
import { queryIsValid } from '../util/state'
1212

13+
export const receivedPlanError = createAction('PLAN_ERROR')
1314
export const receivedPlanResponse = createAction('PLAN_RESPONSE')
1415
export const requestPlanResponse = createAction('PLAN_REQUEST')
1516

1617
export function planTrip (customOtpQueryBuilder) {
17-
return function (dispatch, getState) {
18+
return async function (dispatch, getState) {
1819
const otpState = getState().otp
1920
const latest = otpState.searches.length && otpState.searches[otpState.searches.length - 1]
2021
// check for query change
@@ -27,15 +28,20 @@ export function planTrip (customOtpQueryBuilder) {
2728
const queryBuilderFn = customOtpQueryBuilder || otpState.config.customOtpQueryBuilder || constructPlanQuery
2829
const url = queryBuilderFn(otpState.config.api, otpState.currentQuery)
2930
// setURLSearch(url)
30-
fetch(url)
31-
.then(response => {
32-
if (response.status >= 400) {
33-
throw new Error('Bad response from server')
34-
}
35-
return response.json()
36-
}).then(json => {
37-
dispatch(receivedPlanResponse(json))
38-
})
31+
let response, json
32+
try {
33+
response = await fetch(url)
34+
if (response.status >= 400) {
35+
const error = new Error('Received error from server')
36+
error.response = response
37+
throw error
38+
}
39+
json = await response.json()
40+
} catch (err) {
41+
return dispatch(receivedPlanError(err))
42+
}
43+
44+
dispatch(receivedPlanResponse(json))
3945
}
4046
}
4147

Diff for: lib/components/form/error-message.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ class ErrorMessage extends Component {
1313
if (!error) return null
1414

1515
return (
16-
<div className='error'>
16+
<div className='alert alert-danger error'>
1717
<div className='header'>Error!</div>
18-
<div className='message'>{error.msg}</div>
18+
<div className='message'>{error.message}</div>
1919
</div>
2020
)
2121
}

Diff for: lib/components/form/form.css

+1-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
1-
.otp .error {
2-
margin-bottom: 16px;
3-
padding: 10px;
4-
background-color: #f5f5f5;
5-
border: 1px solid #e3e3e3;
6-
border-radius: 4px
7-
}
8-
91
.otp .error > .header {
102
font-size: 16px;
113
padding-bottom: 4px;
12-
border-bottom: 1px solid black;
13-
margin-bottom: 6px;
4+
border-bottom: 1px solid #dbbec3;
145
}
156

167
.otp .error > .header > .title {

Diff for: lib/index.css

+9
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,12 @@
88
@import url(lib/components/map/map.css);
99
@import url(lib/components/form/form.css);
1010
@import url(lib/components/narrative/narrative.css);
11+
12+
button.header, button.step, .intermediate-stops button {
13+
background: inherit;
14+
color: inherit;
15+
border: 0;
16+
text-align: inherit;
17+
text-decoration: none;
18+
width: 100%;
19+
}

Diff for: lib/reducers/create-otp-reducer.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ function createOtpReducer (config, initialQuery) {
3131
}
3232

3333
return (state = initialState, action) => {
34+
const latestSearchIndex = state.searches.length - 1
3435
switch (action.type) {
3536
case 'PLAN_REQUEST':
3637
return update(state, {
@@ -43,14 +44,25 @@ function createOtpReducer (config, initialQuery) {
4344
activeStep: null
4445
}]}
4546
})
47+
case 'PLAN_ERROR':
48+
return update(state, {
49+
searches: {[latestSearchIndex]: {
50+
planResponse: {
51+
$set: {
52+
error: action.payload
53+
}
54+
},
55+
pending: {$set: false}
56+
}},
57+
activeSearch: { $set: latestSearchIndex }
58+
})
4659
case 'PLAN_RESPONSE':
47-
const latestIndex = state.searches.length - 1
4860
return update(state, {
49-
searches: {[latestIndex]: {
61+
searches: {[latestSearchIndex]: {
5062
planResponse: {$set: action.payload},
5163
pending: {$set: false}
5264
}},
53-
activeSearch: { $set: state.searches.length - 1 }
65+
activeSearch: { $set: latestSearchIndex }
5466
})
5567
case 'SET_ACTIVE_ITINERARY':
5668
if (state.activeSearch !== null) {

0 commit comments

Comments
 (0)