Skip to content

Commit 880c8af

Browse files
committed
Throw exceptions instead of using magical key
1 parent 8bf6653 commit 880c8af

File tree

6 files changed

+39
-16
lines changed

6 files changed

+39
-16
lines changed

docs.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ A function that creates action creators for making stubbed API requests.
350350
Unlike [createRequest][21], these action creators do not make real API calls but rather
351351
resolve immediately with the provided data.
352352

353-
If an `error` key is provided in the stub data object, the "request" will reject with the value of that key instead of resolving.
353+
If an exception is thrown from the data creator function, the "request" will reject with that exception instead of resolving.
354354

355355
### Parameters
356356

@@ -375,7 +375,9 @@ handleActions({
375375

376376
// ** Stubbing a failed request: **
377377

378-
export const fetchUser = createStubRequest('FETCH_USER', (id) => ({ error: new Error('My mock error.') }))
378+
export const fetchUser = createStubRequest('FETCH_USER', (id) => {
379+
throw new Error('My mock error.')
380+
})
379381

380382
fetchUsers(5)
381383
// -> won't make any api request, but will reject with the given error.

src/create-stub-request.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { isObject, isFunction, identity } from 'lodash'
88
* Unlike {@link createRequest}, these action creators do not make real API calls but rather
99
* resolve immediately with the provided data.
1010
*
11-
* If an `error` key is provided in the stub data object, the "request" will reject with the value of that key instead of resolving.
11+
* If an exception is thrown from the data creator function, the "request" will reject with that exception instead of resolving.
1212
*
1313
* @name createStubRequest
1414
* @param {String} type - A unique key that will be used to identify the request internally in redux
@@ -31,27 +31,35 @@ import { isObject, isFunction, identity } from 'lodash'
3131
*
3232
* // ** Stubbing a failed request: **
3333
*
34-
* export const fetchUser = createStubRequest('FETCH_USER', (id) => ({ error: new Error('My mock error.') }))
34+
* export const fetchUser = createStubRequest('FETCH_USER', (id) => {
35+
* throw new Error('My mock error.')
36+
* })
3537
*
3638
* fetchUsers(5)
3739
* // -> won't make any api request, but will reject with the given error.
3840
*
3941
**/
4042

41-
function createActionOptions (definition, args) {
42-
return isFunction(definition)
43-
? definition(...args) || {}
44-
: definition
43+
function getStubData (definition, args) {
44+
if (!isFunction(definition)) return { stubData: definition }
45+
try {
46+
const stubData = definition(...args) || {}
47+
return { stubData }
48+
} catch (e) {
49+
return { stubData: e, isError: true }
50+
}
4551
}
4652

4753
function createStubRequest (type, definition=identity) {
4854
if (!type) throw new Error('Must include a type for your request.')
4955
if (!(isObject(definition) || isFunction(definition))) throw new Error('Request definition must be an object or a function.')
5056
function actionCreator (...args) {
57+
const { stubData, isError } = getStubData(definition, args)
5158
return {
5259
[LP_API]: {
5360
isStub: true,
54-
stubData: createActionOptions(definition, args),
61+
isStubError: isError,
62+
stubData,
5563
type,
5664
}
5765
}

src/middleware/middleware.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ import { isFunction } from 'lodash'
3333
*/
3434

3535
// custom HTTP method for stub requests- makes no call, but resolves/rejects with provided data
36-
function createStubRequest (data) {
36+
function createStubRequest (data, isError) {
3737
return function request () {
3838
return new Promise((resolve, reject) => {
39-
return data.error ? reject(data.error) : resolve(data)
39+
return isError ? reject(data) : resolve(data)
4040
})
4141
}
4242
}
@@ -69,6 +69,7 @@ function middleware (mainAdapter, options={}) {
6969
successAction,
7070
failureAction,
7171
isStub,
72+
isStubError,
7273
stubData,
7374
adapter=mainAdapter,
7475
} = mergedConfigOptions
@@ -82,7 +83,7 @@ function middleware (mainAdapter, options={}) {
8283
// Send built-in request action
8384
next(actions.setStatusLoading(type))
8485
// Make the request
85-
const request = isStub ? createStubRequest(stubData) : adapter
86+
const request = isStub ? createStubRequest(stubData, isStubError) : adapter
8687
return request(mergedRequestOptions)
8788
.then(
8889
// Success handler

src/middleware/parse-options.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ function parseOptions ({
1111
successAction,
1212
failureAction,
1313
isStub,
14+
isStubError,
1415
stubData,
1516
adapter,
1617
...requestOptions
@@ -25,6 +26,7 @@ function parseOptions ({
2526
successAction,
2627
failureAction,
2728
isStub,
29+
isStubError,
2830
stubData,
2931
adapter,
3032
}),

test/create-stub-request.test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ test('createStubRequest accepts function data creator', () => {
2020
expect(action[LP_API]).toEqual({ type: REQUEST_TYPE, isStub: true, stubData: { foo: 'bar' } })
2121
})
2222

23+
test('createStubRequest function sets data and error flag from thrown exception', () => {
24+
const myException = new Error('oops')
25+
const actionCreator = createStubRequest(REQUEST_TYPE, () => {
26+
throw myException
27+
})
28+
const action = actionCreator('bar')
29+
expect(action[LP_API]).toEqual({ type: REQUEST_TYPE, isStub: true, isStubError: true, stubData: myException })
30+
})
31+
2332
test('createStubRequest defaults to identity for data creator', () => {
2433
const actionCreator = createStubRequest(REQUEST_TYPE)
2534
const action = actionCreator('bar')

test/middleware.test.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,18 +149,19 @@ test('middleware resolves stubbed requests with provided data', () => {
149149
})
150150
})
151151

152-
test('middleware rejects stubbed requests with error key', () => {
152+
test('middleware rejects stubbed requests with error flag', () => {
153153
expect.assertions(1)
154-
const ERROR = new Error('mock error')
154+
const stubData = { foo: 'bar' }
155155
const store = mockStore({})
156156
const stubAction = {
157157
[LP_API]: {
158158
isStub: true,
159-
stubData: { error: ERROR }
159+
isStubError: true,
160+
stubData
160161
}
161162
}
162163
return store.dispatch(stubAction).catch((res) => {
163-
expect(res).toEqual(ERROR)
164+
expect(res).toEqual(stubData)
164165
})
165166
})
166167

0 commit comments

Comments
 (0)