-
Notifications
You must be signed in to change notification settings - Fork 4
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
BREAKING CHANGE: make using non-enforcing entity loader explicit #238
Conversation
1c7d887
to
c9f34a5
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #238 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 69 70 +1
Lines 1899 1912 +13
Branches 262 262
=========================================
+ Hits 1899 1912 +13
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Need to add to |
For naming: People expect the default behavior to be that methods return entity objects and throw if there is an error, and the non-default behavior is to return a Some possibilities:
To be comprehensive, I would not do It will also be helpful to document why a result-based loader is even desirable. The most compelling reason IMO is when loading multiple entities or, more generally, performing multiple operations and being able to return the successful status or error for each operation. |
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.
lgtm, I've never actually used a nonEnforcing
entity result (I've always opted to use try-catch instead) so this is a welcome change.
No strong feelings about the naming, but I prefer nonEnforcing
more than the other candidates
I've always thought non enforcing methods just wrapped all the errors in a Failure result, didn't actually realize it was limited to just privacy policy evaluation. How about |
Privacy policies are always enforced by entities, and "enforcing" in this context is unrelated to privacy policies. To me, this is an additional reason to avoid the word "enforcing" in the naming. |
The way non-enforcing works currently is that only privacy policy (and entity constructor) errors are wrapped in a result (see I really like the idea of having the result-based sub-loader name indicate Result-based privacy and construction in the name. Maybe something like As for whether to keep I'll change this to |
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.
Mixed feelings on the name but since it's such a secondary API, I'm ok with moving forward with it.
What I like is that it hints to the reader that not every error is returned in a Result. In contrast, Promise.allSettled always returns Results for all types of errors. That actually could be a good change for us to make but is a separate discussion.
What I don't like is that the name implies the return value has details about an authorization check. Setting aside Results for a moment, if someone says "authorization result" you'd think it'd be some data that contains PASS/FAIL state.
import EntityPrivacyPolicy from './EntityPrivacyPolicy'; | ||
import ReadonlyEntity from './ReadonlyEntity'; | ||
import ViewerContext from './ViewerContext'; | ||
import { mapMap } from './utils/collections/maps'; | ||
|
||
/** | ||
* Enforcing view on an entity loader. All loads through this loader will throw | ||
* if the loads are not successful. | ||
* Enforcing entity loader. All normal loads are batched, |
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.
Out of scope, but renaming this in the future could make sense. The word "enforcing" is confusing except when working with Result objects.
That's an interesting point. I actually had also forgotten that the Result type returned here was only for authorization until reading the code during this series of PRs. If and when we do change this so that all errors are wrapped (which is maybe what we should've done from the beginning), we'd want to have a new loader type, something like
Yeah, I had the same gut feeling. My home though is that the Result type is clear enough to disambiguate the general term "authorization result" from what is meant here. |
Why
This has been discussed many many times and it's long overdue: it's time to make non-enforcing loads not the default. Whether we make enforcing loads the default is another discussion to be had, but is out of the scope of this PR.
This PR introduces a new required intermediate call to loaders to explicitly specify either enforcing or non-enforcing load behavior.
Note that
.enforcing
calls remain unchanged.The reasoning behind this change is that it's too easy to misinterpret a Failure result to also be the result of the call when a database error is thrown from a non-enforcing method, when in fact it's only a Failure when the privacy policy evaluation fails.
In Expo's use of Entity, we almost exclusively use
.enforcing()
, to the point where we want to add a lint rule to discourage non-enforcing. Rather than go down this path, we figure it's better to just make the non-enforcing explicit. And then maybe in the future make enforcing default, though that's a ways in the future to avoid implicit breakage.How reviewers can help
- Help decide on the name for.nonEnforcing
. Note that the.enforcing
method is considered the opposite. Other names I considered are.resultWrapped()
,.asyncResult()
, but I'm sure there are others. I went with.nonEnforcing
since it seemed the clearest.How
Add
.withAuthorizationResults
method toEntityLoader
, add newAuthorizationResultBasedEntityLoader
class, move methods there.In a follow-up, I'll look into moving the common methods (the ones in
knownLoaderOnlyDifferences
) to a different utils class since it no longer makes sense for them not to be on the loader class. But to limit the scope of this PR, they are kept in theAuthorizationResultBasedEntityLoader
class for now.Test Plan
Run all tests.