question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

MalformedContinuationTokenException should be made public

See original GitHub issue

Describe the bug We include CosmosDB continuation token in the nextLink that we return to our API caller during pagination. Sometimes, caller accidentally clip or alter the continuation token when calling us to retrieve the next page. In that case, SDK would throw CosmosException with inner exception MalformedContinuationTokenException. We would like to catch that so we can tell user what’s wrong specifically. However, the latter is an internal class which prevents us from doing so. The only workaround is to parse the CosmosException message which is fragile. Can MalformedContinuationTokenException be made public?

To Reproduce

try 
{
    var iterator = container.GetItemQueryIterator<Foo>(query, continuationToken.Substring(0, continuationToken.Length-1), queryOptions);
    var response = await iterator.ReadNextAsync(ct);
}
catch (CosmosException ex) // when (ex.InnerException is `MalformedContinuationTokenException`)
{
    // ...
}

Expected behavior MalformedContinuationTokenException type is public and can be compared against. Its constructor can remain internal.

Actual behavior The type is internal, so we can’t check against the type.

Environment summary SDK Version: 3.25 OS Version: Windows 11

Additional context Add any other context about the problem here (for example, complete stack traces or logs).

 Microsoft.Azure.Cosmos.CosmosException : Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Malformed Continuation Token: [{"token":"+RID:~oN4fAM-fK9UGAAAAAAAAAA==#RT:3#TRC:6#ISV:2#IEO:65567#QCF:4#FPC:AQYAAAAAAAAACgAAAAAAAAA=","range":{"min":"","max":"FF"}}););
 ---> Microsoft.Azure.Cosmos.Query.Core.Exceptions.MalformedContinuationTokenException: Malformed Continuation Token: [{"token":"+RID:~oN4fAM-fK9UGAAAAAAAAAA==#RT:3#TRC:6#ISV:2#IEO:65567#QCF:4#FPC:AQYAAAAAAAAACgAAAAAAAAA=","range":{"min":"","max":"FF"}}
 ---> Microsoft.Azure.Cosmos.Query.Core.Monads.ExceptionWithStackTraceException: TryCatch resulted in an exception. ---> Microsoft.Azure.Cosmos.Json.JsonMissingEndArrayException: Missing an end array ("]") symbol in JSON., Windows/10.0.22572 cosmos-netstandard-sdk/3.24.1
   at Microsoft.Azure.Cosmos.Json.JsonReader.JsonTextReader.Read()
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseObjectNode(IJsonTextReaderPrivateImplementation jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseNode(IJsonTextReaderPrivateImplementation jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseArrayNode(IJsonTextReaderPrivateImplementation jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseNode(IJsonTextReaderPrivateImplementation jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.Parse(IJsonTextReaderPrivateImplementation jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.<>c__DisplayClass3_0.<.ctor>g__CreateRootNode|0()
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator..ctor(ReadOnlyMemory`1 buffer)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.Create(ReadOnlyMemory`1 buffer)
   at Microsoft.Azure.Cosmos.CosmosElements.CosmosElement.Monadic.CreateFromBuffer[TCosmosElement](ReadOnlyMemory`1 buffer)
   --- End of inner exception stack trace ---
   at Microsoft.Azure.Cosmos.CosmosElements.CosmosElement.Monadic.CreateFromBuffer[TCosmosElement](ReadOnlyMemory`1 buffer)
   at Microsoft.Azure.Cosmos.CosmosElements.CosmosElement.Monadic.Parse[TCosmosElement](String serializedCosmosElement)
   at Microsoft.Azure.Cosmos.CosmosElements.CosmosElement.Monadic.Parse(String serializedCosmosElement)
   at Microsoft.Azure.Cosmos.Query.QueryIterator.Create(ContainerCore containerCore, CosmosQueryClient client, CosmosClientContext clientContext, SqlQuerySpec sqlQuerySpec, String continuationToken, FeedRangeInternal feedRangeInternal, QueryRequestOptions queryRequestOptions, String resourceLink, Boolean isContinuationExpected, Boolean allowNonValueAggregateQuery, Boolean forcePassthrough, PartitionedQueryExecutionInfo partitionedQueryExecutionInfo)
   at Microsoft.Azure.Cosmos.ContainerCore.GetItemQueryStreamIteratorInternal(SqlQuerySpec sqlQuerySpec, Boolean isContinuationExcpected, String continuationToken, FeedRangeInternal feedRange, QueryRequestOptions requestOptions)
   at Microsoft.Azure.Cosmos.ContainerCore.GetItemQueryStreamIterator(QueryDefinition queryDefinition, String continuationToken, QueryRequestOptions requestOptions)
   at Microsoft.Azure.Cosmos.ContainerInlineCore.GetItemQueryStreamIterator(QueryDefinition queryDefinition, String continuationToken, QueryRequestOptions requestOptions)
   at Microsoft.Azure.Cosmos.ContainerCore.GetItemQueryIterator[T](QueryDefinition queryDefinition, String continuationToken, QueryRequestOptions requestOptions)
   at Microsoft.Azure.Cosmos.ContainerInlineCore.GetItemQueryIterator[T](QueryDefinition queryDefinition, String continuationToken, QueryRequestOptions requestOptions)

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (9 by maintainers)

github_iconTop GitHub Comments

2reactions
devliecommented, Mar 10, 2022

Why would the user tamper with the continuation token? Is the user a developer?

Not intentionally we presume - I think they URLDecoded our nextLink and did a split string on =. CosmosDB token often has == in them.

Why returning the actual error (BadRequest with an error message saying the token is malformed) not enough? If the user is a developer, then this would be considered a bug in their code, right?

We indeed would like to return 400 to them. However, when Cosmos DB returns 400 to us, it can theoretically be a bug in our code (e.g., invalid query), or in our user’s code (malformed token in this case). Thus, we can’t just blindly propagate Cosmos DB’s 400 as our service’s 400. We can parse the CosmosException message, but we doubt the message is guaranteed to remain the same forever. During debugging, we notice the underlying exact reason is already in its inner exception, but unfortunately the type is not public.

1reaction
imanvtcommented, Jun 13, 2022

@xiejiams Please see above comment as well.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Continuation token specified in the request is malformed ...
1 Answer 1 ... As the error denotes , it seems that the continuation token is null or in invalid format. ... Follow...
Read more >
Pagination - Azure Cosmos DB for NoSQL
You can optionally use continuation tokens to manage query results that span multiple pages. Query executions. Sometimes query results are split ...
Read more >
Understanding CosmosDB Continuation Tokens ...
The CosmosDB client libraries utilize a continuation strategy when managing the results returning from queries. Every query submitted to ...
Read more >
Error Responses - Amazon Simple Storage Service
Error Code Description HTTP Status Code AccessControlListNotSupported The bucket does not allow ACLs. 400 Bad Request AccessDenied Access Denied 403 Forbidden BucketAlreadyOwnedByYou 409 Conflict (in all...
Read more >
Bitwarden Public API | Bitwarden Help Center
The request was unacceptable, possibly due to missing or malformed parameter(s). 401 Unauthorized. The bearer access token was missing, invalid, or expired. 404 ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found