-
-
Notifications
You must be signed in to change notification settings - Fork 651
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
Make new mentioned/starred messages appear in mentions/starred narrows #3619
Conversation
Also, I used a rebase to reorder the commits so that the eventMiddleware commit (ensuring the existence of message.flags; ca5f351) was done first, since technically it is required to avoid an error that would have been introduced in the 2fa1684 commit, since that commit has a call to .includes on message.flags without first checking that message.flags exists. You can see this reorder in my fork: https://github.com/chrisbobbe/zulip-mobile/commits/issue-3592 but I'm puzzled why my original order (the incorrect order) is showing up here. |
Oh interesting, I can see the test results from Travis; it says, "TypeError: Cannot add property flags, object is not extensible". If
|
Oops -- I didn't see your comment from yesterday on the issue:
until now, having already implemented an opinion about 'wildcard_mentioned' (i.e., that it's a separate flag that needs to be checked everywhere we check 'mentioned'). Sorry about that; I'll make changes of course, as necessary, just let me know. |
Thanks @chrisbobbe !
No problem. This looks like a good simple-to-implement way of handling it; if we end up combining the flags earlier in the pipeline, we can adjust this code then.
Ah, so: look closely at the top and bottom of the failure text you quoted. This is happening when running
That's the So I think it's caused by the (Whether using mutation here is a good idea is another question. Most likely it isn't and we'd be better off keeping things unmutated and making a new object here, just as we do in the bulk of the app. But that's probably a larger refactor.) The bigger thing the CI run finds is actually a series of Flow errors. These are all of the form:
That's because the
You can run our test suite with Specific comments coming next. |
Perfect, thanks!
Yeah, this is unfortunately a longtime bug in GitHub: they'll show commits inappropriately ordered by author date, making them out of order compared to the actual Git history. (My guess has always been that someone decided topo-sorting was too hard and/or complicated, and wasn't fully aware of Git committer dates -- sorting by committer date would be implemented almost exactly the same as by author date, and fix the problem in almost all cases. But who knows.) When reviewing a PR, I fetch it locally and mainly read it with |
ca5f351 eventMiddleware: Set event.message.flags to [] even if absent on event.I like this change! It makes the behavior simpler to describe, and also brings it in line with what that comment on Test failure needs to be fixed; discussed above. This step isn't enough to make it possible for the rest of the app to become a "soft center" with respect to this property's presence, because in the Redux state we leave it off and maintain the flags data separately. But it's still a move in the right direction. 2fa1684 isMessageInNarrow: Fix check for starred or mentioned messages.This looks good, except the Flow error. I believe that at each call site it's actually the case that this I think the best immediate fix is to just include the presence checks that the type says are necessary. Hmm, or for a more principled alternative: assert the property is there (i.e. throw an error if not.) That way if we do introduce a bug where the property is missing here because the flags are located elsewhere, we'll almost certainly notice in dev, rather than silently behave as if all flags are false. (But if that gets cumbersome, no need; as the next commit shows, the status quo is already that we just do the presence checks and silently assume that if there were flags set they'd be present here.) 3e53bf7 Fix 2 checks of 'mentioned' flag without checking 'wildcard_mentioned'Thanks for this fix! I agree this is the right behavior in both of these spots. This version causes Flow errors much like the parent, for the same reason. 4638c8c narrowsReducer/eventUpdateMessageFlags: Handle mentioned/wildcard_mentionedThis looks right! I'd like to avoid duplicating the code in this block, though. How about factoring it out into a function so that we can say something like
Then to handle mentions is a short |
Oh OK, yes, I can see now that the test results showing the flow issues and the "object is not extensible" message do indeed show up when testing in my local development environment. I saw the 20 occurrences of "SyntaxError: Unexpected token import" (shown in the .txt doc in my first post here) and assumed that there was some Babel mis-configuration interfering with all tests, without looking closer to see that some tests did run properly. It looks like this error is thrown in all 20 cases by this line in src/compose/ComposeMenu.js, a file not touched by my commits:
and it appears that that import has caused issues before; it's preceded by this comment:
Deferring the import doesn't seem to have helped much, or else it fixed the original warning and caused this new error; could it be that there was an additional workaround outside source control, like (somehow?) some more Babel configuration, that most developers have, but I don't, since I just recently cloned the project? |
Hmm, so I've tried a few different things for this. Currently, it looks like this:
All three calls to .includes() result in Flow errors because there is no check that .flags is defined, as you've said. For the least amount of repeating myself, I tried adding a single assertion above:
All three Flow errors remained. Despite the assertion, apparently Flow can't be reasonably sure that Next, I tried a version that does include repeating myself, but at least is relatively compact, since it uses a ternary instead of if/else blocks.
This didn't work; many more errors were triggered (Flow errors with ternary attempt.txt). My first guess is that it isn't acceptable for Finally, I tried fully fledged if/else blocks:
That did fix it for the first two sites of
So maybe we're at the point of "too cumbersome," unless you see something else I could try. |
Ah, apologies, I looked right past that yesterday. I believe this means you're using Node 8, and the fix is to use Node 10 (the current LTS). The incompatibility with Node 8 was introduced last week in 338036e; it actually broke things in CI until 091bdc3 a few commits later. The error is pretty unhelpful. Because the incompatibility is only a week old, I think you may be the first person to have gotten bitten by it. We should make that easier to debug; I might try putting a Node version check right in I'd appreciate seeing what |
And to answer these questions directly (though you might be able to deduce some of these answers from the diagnosis above):
|
Ah, and this at least shouldn't be a problem -- avoiding that kind of discrepancy is Yarn's job, with
should mean that Upgrades are done explicitly with e.g. |
Yeah. I think specifically the issue is that The most common fix for this kind of thing is to say something like
and then have both the check and the use refer to In our codebase this is mostly a (small) annoyance, because for most objects the truth is they never get mutated. In codebases where mutation is routine, and especially those with a lot of concurrency, this pattern is actually a very important one for avoiding some frustrating bugs. |
Ah, yeah. It's the same principle at work as in your first version:
Here, it's that once the first So the general fix to make a guard condition stay good is to make a local |
Yep, that was it, thank you!
Brilliant, this worked! Yes, I was referring to the possibility of mutation with "which I guess is defensible on Flow's part, if a little annoying"; I just took a step back when I saw that an assertion is respected for code that immediately follows it, so I wasn't sure how far away was "too far away," and how that immediacy is determined.
This sounds correct for what's going on here; some supporting examples to follow.
And this sounds reasonable as the policy to determine where "too far away" is -- it's easy on computation; like you said, it can't spend too many resources predicting state in runtime or it wouldn't scale. Some tweaking confirms that you can introduce arbitrary code between the check and the call to
Surprisingly, it still doesn't trigger the error in the following case, presumably because there are still no function calls:
EDIT: Ah, I did finally trigger the error without a function call in a pretty obvious way (below), but the
|
Hmm, indeed! It looks like the Flow bug here is centered on
Looks like facebook/flow#6567 probably covers this, and facebook/flow#7089 seems closely related. |
3b7078e
to
b6d64d8
Compare
Nice; I had a vague feeling the lock file could also be updated with a I've made some changes to address your feedback; the plus sign (+) tip at https://zulip.readthedocs.io/en/latest/git/fixing-commits.html#pushing-commits-after-tidying-them really helped me out when I thought I was stuck, with no way to avoid introducing a merge commit! :) |
b6d64d8
to
cea9106
Compare
The conditional described by the comment "move `flags` key from `event` to `event.message` for consistency" was not defaulting `event.message.flags` to an empty array in cases where `flags` is absent on `event`. Defaulting to an empty array will give more resistance to unpredictable input, in a crunchy shell pattern: https://github.com/zulip/zulip-mobile/blob/master/docs/architecture/crunchy-shell.md This commit replaces a test from 25e97ef (fixed zulip#3046) that ensured the opposite (!): that `event.message` was not mutated in the case where `event.message.flags` was not set. I didn't see an obvious reason for this test, and an explanation wasn't given in the commit message. If possible, I do think it's important to have a dependable empty value for event.message.flags, so we don't have to constantly check internally if it's defined.
Newly arriving messages did not appear in the is:starred narrow if they were starred, or in the is:mentioned narrow if they contained an @-mention (either direct or wildcard). In isMessageInNarrow (src/utils/narrow.js), instead of checking if message.type is 'starred' or 'mentioned' -- which didn't work, because it never has those values -- we now correctly check for the relevant values in message.flags . Also add tests for this logic. We also assert (with an error) that message.flags is defined. It should be; see parent commit, and if not, this will help us catch the bug in dev. Add a test for this exception, and update existing tests to include message.flags. Fixes: zulip#3592
Everywhere that we want to check direct mentions, we also want to check wildcard mentions. Add such a check in two spots. Also convert the case where action.message.flags is missing into an exception, rather than a silent no-flags-are-set, for the same reasons as in the parent commit.
The 'starred' flag was already handled for this action type. Add handling for 'mentioned' and 'wildcard_mentioned'. To avoid repeating code, the shared logic was extracted into a helper function updateFlagNarrow.
…AGE_FLAGS. Add an assertion to match the type in EventUpdateMessageFlagsAction in src/actionTypes.js, so that action.operation can only be 'add' or 'remove'.
This would cause Flow to give an error if there were any way to reach this case consistent with the stated types. The line that throws an exception is still helpful too, because like much of our data this action object comes largely from the server -- so there's no static guarantee that it actually *does* follow the stated types. (This is an area where we don't currently have much of a "crunchy shell".)
If you're using Node 8.x, the previous LTS version, then 338036e causes every test that would import `ComposeMenu.js` (which is a large fraction of them) to break with a loud syntax error, as described in the parent commit. Our setup instructions in build-run.md say to use Node 10.x, but that's pretty easy to miss, especially if you already have Node lying around; and the syntax errors are not very helpful for diagnosing the problem. (See e.g. zulip#3619.) So, make our own quick version check first. (With Node 11.x there's a *different* issue described in the troubleshooting section of build-run.md . But that comes before this step anyway, so there's nothing to be gained by enforcing an upper bound here; may as well leave it open for when Node versions >= 11 do eventually work.) I'm actually puzzled why the Node version matters here, because I'd have thought it's Babel's job to compile the fancy syntax out. As the commit message on 338036e says, our Babel config appears to have the plugin enabled that would compile this syntax out. I suspect there's something wrong in our Jest config for Babel, but haven't dug into it. In any case it seems for the best to standardize on a version of Node.
And merged. Thanks again @chrisbobbe for the thorough fix and for the revisions! Seeing the |
You're welcome, glad to help!
Noted, thanks! |
Fixes #3592.
I ran into some Babel issues with Jest and haven't been able to run the tests yet; could you please take a quick look at the logs (attached) to see if this is a known issue? Since I'm assuming everything works for people with development environments that have been set up for a while, and the error was thrown from code I didn't touch, there may have been a breaking change in a minor version of Babel or Jest that was triggered by the carat in package.json allowing silent minor version upgrades (e.g., "jest": "^24.8.0"), but that's just a guess until I can dig deeper or learn that it's a known issue.
Issue 3592 Test Output (babel issue?).txt
I'm proposing a change to the eventMiddleware logic (first commit) that would ensure that
flags
is always set onaction.message.flags
, at least as an empty array, ifevent.flags
does not exist, to help with the "crunchy shell" pattern: https://github.com/zulip/zulip-mobile/blob/master/docs/architecture/crunchy-shell.md.