Skip to content

Commit 4258ba7

Browse files
authored
Merge pull request reduxjs#4057 from reduxjs/feature/4x-error-messages
Former-commit-id: a50d018
2 parents 1bb98f7 + ebc2649 commit 4258ba7

11 files changed

+125
-13
lines changed

errors.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"0": "It looks like you are passing several store enhancers to createStore(). This is not supported. Instead, compose them together to a single function. See https://redux.js.org/tutorials/fundamentals/part-4-store#creating-a-store-with-enhancers for an example.",
3+
"1": "Expected the enhancer to be a function. Instead, received: ''",
4+
"2": "Expected the root reducer to be a function. Instead, received: ''",
5+
"3": "You may not call store.getState() while the reducer is executing. The reducer has already received the state as an argument. Pass it down from the top reducer instead of reading it from the store.",
6+
"4": "Expected the listener to be a function. Instead, received: ''",
7+
"5": "You may not call store.subscribe() while the reducer is executing. If you would like to be notified after the store has been updated, subscribe from a component and invoke store.getState() in the callback to access the latest state. See https://redux.js.org/api/store#subscribelistener for more details.",
8+
"6": "You may not unsubscribe from a store listener while the reducer is executing. See https://redux.js.org/api/store#subscribelistener for more details.",
9+
"7": "Actions must be plain objects. Instead, the actual type was: ''. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples.",
10+
"8": "Actions may not have an undefined \"type\" property. You may have misspelled an action type string constant.",
11+
"9": "Reducers may not dispatch actions.",
12+
"10": "Expected the nextReducer to be a function. Instead, received: '",
13+
"11": "Expected the observer to be an object. Instead, received: ''",
14+
"12": "The slice reducer for key \"\" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined. If you don't want to set a value for this reducer, you can use null instead of undefined.",
15+
"13": "The slice reducer for key \"\" returned undefined when probed with a random type. Don't try to handle '' or other actions in \"redux/*\" namespace. They are considered private. Instead, you must return the current state for any unknown actions, unless it is undefined, in which case you must return the initial state, regardless of the action type. The initial state may not be undefined, but can be null.",
16+
"14": "When called with an action of type , the slice reducer for key \"\" returned undefined. To ignore an action, you must explicitly return the previous state. If you want this reducer to hold no value, you can return null instead of undefined.",
17+
"15": "Dispatching while constructing your middleware is not allowed. Other middleware would not be applied to this dispatch.",
18+
"16": "bindActionCreators expected an object or a function, but instead received: ''. Did you write \"import ActionCreators from\" instead of \"import * as ActionCreators from\"?"
19+
}

rollup.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export default [
3737
extensions,
3838
plugins: [
3939
['@babel/plugin-transform-runtime', { version: babelRuntimeVersion }],
40+
['./scripts/mangleErrors.js', { minify: false }]
4041
],
4142
babelHelpers: 'runtime'
4243
})
@@ -62,6 +63,7 @@ export default [
6263
'@babel/plugin-transform-runtime',
6364
{ version: babelRuntimeVersion, useESModules: true }
6465
],
66+
['./scripts/mangleErrors.js', { minify: false }]
6567
],
6668
babelHelpers: 'runtime'
6769
})
@@ -82,6 +84,7 @@ export default [
8284
babel({
8385
extensions,
8486
exclude: 'node_modules/**',
87+
plugins: [['./scripts/mangleErrors.js', { minify: true }]],
8588
skipPreflightCheck: true
8689
}),
8790
terser({
@@ -111,6 +114,7 @@ export default [
111114
babel({
112115
extensions,
113116
exclude: 'node_modules/**',
117+
plugins: [['./scripts/mangleErrors.js', { minify: false }]]
114118
}),
115119
replace({
116120
'process.env.NODE_ENV': JSON.stringify('development')
@@ -134,6 +138,7 @@ export default [
134138
babel({
135139
extensions,
136140
exclude: 'node_modules/**',
141+
plugins: [['./scripts/mangleErrors.js', { minify: true }]],
137142
skipPreflightCheck: true
138143
}),
139144
replace({
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fcd7e7391da1cb7ac4a9fb471298f91474f47043

src/bindActionCreators.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { kindOf } from './utils/kindOf'
2+
13
function bindActionCreator(actionCreator, dispatch) {
24
return function () {
35
return dispatch(actionCreator.apply(this, arguments))
@@ -32,9 +34,9 @@ export default function bindActionCreators(actionCreators, dispatch) {
3234

3335
if (typeof actionCreators !== 'object' || actionCreators === null) {
3436
throw new Error(
35-
`bindActionCreators expected an object or a function, instead received ${
36-
actionCreators === null ? 'null' : typeof actionCreators
37-
}. ` +
37+
`bindActionCreators expected an object or a function, but instead received: '${kindOf(
38+
actionCreators
39+
)}'. ` +
3840
`Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`
3941
)
4042
}

src/combineReducers.js.REMOVED.git-id

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
dcf06f2829ebc3ab3c0c9f85735e81e32b36eeb6
1+
6ed79c245ca26e73bacd6cd91db6ddb0d1104c51

src/createStore.js.REMOVED.git-id

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
45b09aca009a5a9a2298800982c77b87e45b47ab
1+
5326a52ff8a82cca2a564d2f5b6eaf16396411f7

src/utils/formatProdErrorMessage.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Adapted from React: https://github.com/facebook/react/blob/master/packages/shared/formatProdErrorMessage.js
3+
*
4+
* Do not require this module directly! Use normal throw error calls. These messages will be replaced with error codes
5+
* during build.
6+
* @param {number} code
7+
*/
8+
function formatProdErrorMessage(code) {
9+
return (
10+
`Minified Redux error #${code}; visit https://redux.js.org/Errors?code=${code} for the full message or ` +
11+
'use the non-minified dev environment for full errors. '
12+
)
13+
}
14+
15+
export default formatProdErrorMessage

src/utils/kindOf.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
export function kindOf(val) {
2+
let typeOfVal = typeof val
3+
4+
if (process.env.NODE_ENV !== 'production') {
5+
// Inlined / shortened version of `kindOf` from https://github.com/jonschlinkert/kind-of
6+
function miniKindOf(val) {
7+
if (val === void 0) return 'undefined'
8+
if (val === null) return 'null'
9+
10+
const type = typeof val
11+
switch (type) {
12+
case 'boolean':
13+
case 'string':
14+
case 'number':
15+
case 'symbol':
16+
case 'function': {
17+
return type
18+
}
19+
default:
20+
break
21+
}
22+
23+
if (Array.isArray(val)) return 'array'
24+
if (isDate(val)) return 'date'
25+
if (isError(val)) return 'error'
26+
27+
const constructorName = ctorName(val)
28+
switch (constructorName) {
29+
case 'Symbol':
30+
case 'Promise':
31+
case 'WeakMap':
32+
case 'WeakSet':
33+
case 'Map':
34+
case 'Set':
35+
return constructorName
36+
default:
37+
break
38+
}
39+
40+
// other
41+
return type.slice(8, -1).toLowerCase().replace(/\s/g, '')
42+
}
43+
44+
function ctorName(val) {
45+
return typeof val.constructor === 'function' ? val.constructor.name : null
46+
}
47+
48+
function isError(val) {
49+
return (
50+
val instanceof Error ||
51+
(typeof val.message === 'string' &&
52+
val.constructor &&
53+
typeof val.constructor.stackTraceLimit === 'number')
54+
)
55+
}
56+
57+
function isDate(val) {
58+
if (val instanceof Date) return true
59+
return (
60+
typeof val.toDateString === 'function' &&
61+
typeof val.getDate === 'function' &&
62+
typeof val.setDate === 'function'
63+
)
64+
}
65+
66+
typeOfVal = miniKindOf(val)
67+
}
68+
69+
return typeOfVal
70+
}

test/bindActionCreators.spec.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,26 +75,26 @@ describe('bindActionCreators', () => {
7575
expect(() => {
7676
bindActionCreators(undefined, store.dispatch)
7777
}).toThrow(
78-
'bindActionCreators expected an object or a function, instead received undefined. ' +
79-
'Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?'
78+
`bindActionCreators expected an object or a function, but instead received: 'undefined'. ` +
79+
`Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`
8080
)
8181
})
8282

8383
it('throws for a null actionCreator', () => {
8484
expect(() => {
8585
bindActionCreators(null, store.dispatch)
8686
}).toThrow(
87-
'bindActionCreators expected an object or a function, instead received null. ' +
88-
'Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?'
87+
`bindActionCreators expected an object or a function, but instead received: 'null'. ` +
88+
`Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`
8989
)
9090
})
9191

9292
it('throws for a primitive actionCreator', () => {
9393
expect(() => {
9494
bindActionCreators('string', store.dispatch)
9595
}).toThrow(
96-
'bindActionCreators expected an object or a function, instead received string. ' +
97-
'Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?'
96+
`bindActionCreators expected an object or a function, but instead received: 'string'. ` +
97+
`Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`
9898
)
9999
})
100100
})
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
cfd712da380142f8aba47f37add1db132a57febf
1+
a72c1541dd446692cf3bc2496e99a838f4ea93c2
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
9bbac18428e62d57a68306a56c5e17ce6e55f13d
1+
dcbf65cf3e5d3da0bf7bd0a1934b8951120f395c

0 commit comments

Comments
 (0)