Skip to content
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

Improve handling of invalid leg reference #5784

Merged

Conversation

vpaturet
Copy link
Contributor

@vpaturet vpaturet commented Apr 4, 2024

Summary

When OTP fails to base64-decode an invalid serialized leg reference, this is currently reported as a server error with the following error message :

Exception while fetching data (/leg) : Last unit does not have enough valid bits
java.lang.IllegalArgumentException: Last unit does not have enough valid bits
	at java.base/java.util.Base64$Decoder.decode0(Base64.java:872)
	at java.base/java.util.Base64$Decoder.decode(Base64.java:570)
	at java.base/java.util.Base64$Decoder.decode(Base64.java:593)
	at org.opentripplanner.model.plan.legreference.LegReferenceSerializer.decode(LegReferenceSerializer.java:54)
	at org.opentripplanner.apis.transmodel.TransmodelGraphQLSchema.lambda$create$56(TransmodelGraphQLSchema.java:1605)
	at graphql.execution.ExecutionStrategy.invokeDataFetcher(ExecutionStrategy.java:311)
	at graphql.execution.ExecutionStrategy.fetchField(ExecutionStrategy.java:287)
	at graphql.execution.ExecutionStrategy.resolveFieldWithInfo(ExecutionStrategy.java:213)
	at graphql.execution.AsyncExecutionStrategy.execute(AsyncExecutionStrategy.java:55)
	at graphql.execution.Execution.executeOperation(Execution.java:161)
	at graphql.execution.Execution.execute(Execution.java:103)
	at graphql.GraphQL.execute(GraphQL.java:568)
	at graphql.GraphQL.lambda$parseValidateAndExecute$13(GraphQL.java:487)
	at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187)
	at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2341)
	at graphql.GraphQL.parseValidateAndExecute(GraphQL.java:482)
	at graphql.GraphQL.lambda$executeAsync$9(GraphQL.java:440)
	at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187)
	at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2341)
	at graphql.GraphQL.executeAsync(GraphQL.java:428)
	at graphql.GraphQL.execute(GraphQL.java:366)
	at org.opentripplanner.apis.transmodel.TransmodelGraph.executeGraphQL(TransmodelGraph.java:67)
	at org.opentripplanner.apis.transmodel.TransmodelAPI.getGraphQL(TransmodelAPI.java:114)

This PR ensures that the response returns an empty result and the decoding error is reported at INFO level in the logs.

Issue

No

Unit tests

Added unit tests.

Documentation

No

@vpaturet vpaturet added Improvement A functional improvement Skip Changelog labels Apr 4, 2024
@vpaturet vpaturet requested a review from a team as a code owner April 4, 2024 07:06
Copy link

codecov bot commented Apr 4, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 67.86%. Comparing base (978424c) to head (8754908).
Report is 16 commits behind head on dev-2.x.

Additional details and impacted files
@@              Coverage Diff              @@
##             dev-2.x    #5784      +/-   ##
=============================================
+ Coverage      67.81%   67.86%   +0.04%     
- Complexity     16531    16543      +12     
=============================================
  Files           1906     1906              
  Lines          72277    72295      +18     
  Branches        7443     7444       +1     
=============================================
+ Hits           49016    49062      +46     
+ Misses         20740    20713      -27     
+ Partials        2521     2520       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

var input = new ByteArrayInputStream(buf);
byte[] serializedLegReference;
try {
serializedLegReference = Base64.getUrlDecoder().decode(legReference);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of interest: are you supposed to create a new decoder for every call or can you re-use the instance? (Doesn't make a difference for the review of this PR)

Copy link
Contributor Author

@vpaturet vpaturet Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Base64.getUrlDecoder() returns a thread-safe singleton instance.

@vpaturet
Copy link
Contributor Author

I had second thoughts about the log severity for incompatible serialized leg format: while an error in base64 encoding is almost certainly a client error and should be logged at INFO level, an incompatible serialized format is likely to be a deployment issue that should be logged at higher severity. WARN sounds more appropriate.

@vpaturet vpaturet added the Entur Test This is currently being tested at Entur label Apr 10, 2024
@vpaturet vpaturet merged commit 587162b into opentripplanner:dev-2.x Apr 15, 2024
5 checks passed
@t2gran t2gran added this to the 2.6 (next release) milestone May 7, 2024
@t2gran t2gran deleted the improve_invalid_leg_reference_handling branch October 9, 2024 21:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Entur Test This is currently being tested at Entur Improvement A functional improvement Skip Changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants