Add helper to report lazy loading violations #678
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In Laravel you can instruct Eloquent to report whenever you forget to eager load a relation (causing N+1 problems) and you can register a callback to report those exceptions in production instead of throwing an exception breaking your application. Since a lazy loading violation is a performance problem and not a app-breaking problem it is common to forward these to the logs and Sentry by doing the following:
See Laravel docs: https://laravel.com/docs/10.x/eloquent-relationships#preventing-lazy-loading.
This uses the
report
helper to report the exception to the framework logging it to the log files and to Sentry (if installed).I propose a new helper that allows you to do the following:
This is a little syntax sugar over the manual method and also adds a "context" with information about the violation (even though all that information is already available to the user via the exception message and the shown backtrace) but also set's the exception as handled and set's the level to warning.
There is a notable upside to this, and that is that since the exception is created in our vendored code it is marked as not in-app and the stacktrace therefore shows the correct line where the violation occured from instead of the users service provider where the violation would otherwise most likely be reported from.
We could simplify this even more but I am concerned that that would cause undefined behaviour since I don't find it clear that when you'd call something like
Integration::reportLazyLoadingViolations()
that we'd only do that in production (what about other env's like staging?) and such so I opted to go for the more explicit route.