In the e-commerce company I work at, we have many microservices to handle various pieces of a buying experience. In this distributed computing environment we use Graylog as a log aggregator/repository. Running on top of Graylog data, we have some automated reports to aggregate any messages with level ERROR. I noticed that one of those logs could be safely demoted from ERROR to WARN if triggered by an exception with a specific error code.
I talked to my colleagues, and we agreed on that small change: check if the exception contains the error code we want and log it as WARN or keep logging as ERROR otherwise.
To achieve that I created a `public final static int` constant to store the error code I was looking for and wrote the logic to check for it and act accordingly.
The constant got added to a class on the `x-framework-response` Gradle submodule, and it was used on another class within the `x-framework-rate-limit` submodule.
Pretty simple stuff, but it failed to compile on GitLab:
/builds/platform/x-framework/x-framework-rate-limit/src/main/java/com/company/x/framework/ratelimit/RateLimitingFilter.java:100: error: cannot find symbol
.map(c -> c.getCode() == ExceptionMapper.RATE_LIMIT_EXCEEDED)
^
symbol: variable RATE_LIMIT_EXCEEDED
location: class ExceptionMapper
How could that happen? The new constant was there in the same PR, and: it compiled in my local environment (to no one’s surprise!).
We recently migrated most of our code from Gradle 4.10.2 to 6.7.1 (we are now moving to 7.3.x), but we have many repos, and we decided that the smaller ones we would handle on an on-need-basis. It so happens that (questionable past decision incoming): the `x-framework-rate-limit` submodule uses a `ratelimiter-client`, which has a dependency on `x-framework-response`.
When running the build on GitLab the `ExceptionMapper` class that the build was looking at was not the one from the pull request itself but an old one coming as a transitive dependency because of the `ratelimiter-client`. One of the reasons for this to happen is that Gradle 4 artifacts that declare `compile(“x-framework:x-framework-response:${version}”)` leak that dependency to its “consumers” as opposed to what happens if you use `implementation(“x-framework:x-framework-response:${version}”)` from Gradle 6.
So in the end the fix was to migrate `ratelimiter-client` to Gradle 6 (changing `compile()` to `implementation()` or `api()` accordingly) and updating that dependency on the `x-framework` Gradle config.
I still don’t know how the dependency resolution on my local gave precedence to the new `ExceptionMapper` class, and GitLab decided otherwise. I might need to correct something else on the build configuration.
Dependencies “leaking” when they shouldn’t is sure to give headaches eventually. It is best for everyone best interest to tidy this up and avoid having to give an update on your stand up saying it took you a whole day to change a log level 🙂