-
Notifications
You must be signed in to change notification settings - Fork 297
fix(handleAction): Add descriptive error for missing or invalid actions #141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(handleAction): Add descriptive error for missing or invalid actions #141
Conversation
if (!includes(actionTypes, action.type.toString())) { | ||
return state; | ||
} | ||
|
||
return (action.error === true ? throwReducer : nextReducer)(state, action); | ||
}; | ||
} | ||
|
||
function isValidFSA(action) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah - yes. Will change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though, that method doesn't check if the type
is a String
or Symbol
. I'll go make a PR there ;) [unless you're opposed]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well... actually...
The
type
of an action identifies to the consumer the nature of the action that has occurred. Two actions with the sametype
MUST be strictly equivalent (using ===). By convention,type
is usually string constant or a Symbol.
The wording here tells me I probably shouldn't enforce types on the type
property? Say if someone wanted to use numbers for their types for whatever reason. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. Though, we may be dropping Symbol support soon #126.
@@ -12,10 +14,18 @@ export default function handleAction(actionType, reducers, defaultState) { | |||
: [reducers.next, reducers.throw].map(reducer => (isNil(reducer) ? identity : reducer)); | |||
|
|||
return (state = defaultState, action) => { | |||
if (!isValidFSA(action)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we standardize on invariant
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you teach me what invariant
does/is for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done :)
@@ -0,0 +1,16 @@ | |||
root = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with .editorconfig
. Can you quickly teach me what value this adds?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure! EditorConfig is really good for keeping line endings, indentation, trailing spaces and so on and so forth in sync between different IDEs. It's just a quick headache reducer as long as contributors have it installed in their editors (some of which have it bundled out of the box).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool. I recently switched from Webstorm back to Sublime Text, so it looks like I'll have to download a plugin.
What happens if a rule here is broken? Does the build fail? What value does this add beyond linting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't do linting, it just works inside the editor make those things happen (eg. tabs = 2 spaces, or all files get a newline at the end).
Upstream PR for enforcing the |
Could we make a separate PR and issue for the unrelated changes (adding That would help clarify the scope of this PR and make it more targeted. |
@yangmillstheory made separate PRs :) #142 and #143. |
@@ -3,3 +3,4 @@ coverage | |||
*.log | |||
lib | |||
dist | |||
.idea |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you create a single commit or pr for this as well pls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const action1 = createAction('ACTION_1'); | ||
const reducer = handleAction( | ||
action1, | ||
(state) => state |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this and the tests below:
- can we use the identity function from lodash?
- can we inline the call to
createAction
(action1
is not used elsewhere)?
Also, unless there's a good reason to disablemax-len
, let's stick to it. Since we're testing an exact match, can we use the string directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
max-len
is because the message is longer than 100 characters, so I think it's reasonable to disable it. The regex was in case any of you wanted to change the message edit: ie. have a little less dependence in the test on the exact message... but obviously ATM it's just a direct copy/paste.
The build is failing. I'd like to get this in (great contribution that should have been there at the outset since we're explicitly for FSA), so let's make sure that it passes as soon as we can. |
@yangmillstheory I've made redux-utilities/flux-standard-action#36 pass CI, but it needs to be merged and released to unblock CI here... edit: of course that being said I got carried away again and it may need to be split into several PRs. Although, I do think it's valuable because it's a smaller library and it upgrades everything in one shot and takes care of all the JS-fatigue-babel-and-dependencies things [I found myself laughing] cc @acdlite |
We're planning on dropping Symbol support soon #126 (please see the linked discussions there). I'm not sure it's worth waiting on upstream support for Symbols. |
@yangmillstheory good point, but upstream only checks if It will be easy enough to remove support for Symbols in the next |
I'm not sure that the last test (or the upstream PR) is a requirement for this merge. While I agree it's technically correct to enforce that the action type is a string (per the FSA spec IIRC), anyone who would explicitly pass What other tests are failing beyond that one? |
@yangmillstheory that's the only test that's failing, but I would say that the explicit type-check is blocking since it's not spec-compliant. I think I see what you're saying about being able to merge without that test passing since it's not necessarily a "valid use case" (i.e. nobody will actually do it) but I'd personally rather be explicit first. Up to you all as maintainers though. |
I'll publish a new version of |
@yangmillstheory @timche updated :) really ready to merge now. |
const reducer = handleAction(createAction('ACTION_1'), identity); | ||
expect(() => reducer(undefined)) | ||
// eslint-disable-next-line max-len | ||
.to.throw(/The FSA spec mandates an action object with a type. Try using the createAction\(s\) method./); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to push back again on the eslint-disable-next-line max-len
and the use of a regular expression here.
I'd like to use these overrides only where they must be used. In a 20K line production application, I've seen this happen only in two places:
- directly consuming snake-cased fields from the API on the client (
eslint-disable-next-line camelcase
) - early returns from iterators in
lodash
(eslint-disable-next-line consistent-return
)
It wouldn't be a rule if we were permissive about bypassing it; the value of the rule comes from a widespread adherence.
I also think we should strive for consistency with respect to similar tests in the repo.
To that end, let's test the error class thrown, so callers know what to catch, and the exact string (I don't think the flexibility afforded by using a regular expression object buys us much).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Thanks for the feedback!
invariant
only throws a regular Error
and I didn't want to introduce matchers just to check for the error name to be "Invariant Violation". I didn't see it being much value, but the format should be consistent now.
I'm "dismissing" @timche's review since all asks have been addressed. I'm also changing the merge target branch from In the future, let's strive to create more targeted PR's with smaller diffs. That will ensure that reviews are more focused and less noisy. Thanks for the contribution! |
All comments have been addressed
@JaKXz can you fetch the upstream |
according to the FSA spec
and fix lint issues
@yangmillstheory done. Anything I can do to help #127 get merged? |
@yangmillstheory this might be redundant or overkill so feel free to close - but it might be helpful to folks like me to see a more descriptive error when we forget the action type (with the helpful suggestion to use
creatAction
orcreateAction(s)
)I also took the liberty of adding an.editorconfig
and ignoring the JetBrains.idea
folder. And removing Node 5 from testing since it's past it's useful life. If any of these bother you I can quickly rebase this and take those changes out.Resolves #145.