fix(PageConnection): fallback to 0, not -1 on empty pages#9412
fix(PageConnection): fallback to 0, not -1 on empty pages#9412Hanskrogh wants to merge 5 commits intoChilliCream:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR changes the default TotalCount value exposed by PageConnection<TNode> when the underlying GreenDonut.Data.Page<TNode>.TotalCount is not available, switching the fallback from -1 to 0.
Changes:
- Update
PageConnection<TNode>.TotalCountto return0when_page.TotalCountisnull(previously-1).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/HotChocolate/Core/src/Types.CursorPagination.Extensions/PageConnection.cs
Outdated
Show resolved
Hide resolved
| /// </summary> | ||
| [GraphQLDescription("Identifies the total count of items in the connection.")] | ||
| public int TotalCount => _page.TotalCount ?? -1; | ||
| public int TotalCount => _page.TotalCount ?? 0; |
There was a problem hiding this comment.
This changes the sentinel value for "total count not available" from -1 to 0 for PageConnection, but other paging implementations in this repo still use -1 when the total count is unknown (e.g. CursorPagingHandler and OffsetPaginationAlgorithm). Consider aligning the behavior across paging result types or documenting the differing semantics to avoid surprising API consumers.
There was a problem hiding this comment.
@michaelstaib Is this a valid argument? should I change it, so only Page.Empty adds a 0 count?
/// <summary>
/// An empty page.
/// </summary>
public static new ValueCursorPage<T> Empty { get; } = new([], false, false, _ => string.Empty, 0);
src/HotChocolate/Core/src/Types.CursorPagination.Extensions/PageConnection.cs
Outdated
Show resolved
Hide resolved
…geConnection.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
| /// Identifies the total count of items in the connection. | ||
| /// </summary> | ||
| [GraphQLDescription("Identifies the total count of items in the connection.")] | ||
| public int TotalCount => _page.TotalCount ?? -1; | ||
| public int TotalCount => _page.TotalCount ?? _page.Count; |
There was a problem hiding this comment.
This is wrong. I thought we had this fallback in a different location.
TotalCount should not be displayed if, like not be in the typesystem if the page does not provide it. If you have this it seems there is something misconfigured.
Actually, what we should do here is throw a GraphQLException that no count is available.
|
@michaelstaib |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| public int TotalCount => | ||
| _page.TotalCount ?? throw new GraphQLException("Total count is not available for this connection."); |
There was a problem hiding this comment.
This implementation no longer “falls back to 0” when the total count is unavailable; it now throws a GraphQLException when _page.TotalCount is null. That’s a behavior change vs both the PR description/title and existing Page->Connection conversion which uses page.TotalCount ?? 0 (e.g. HotChocolatePaginationResultExtensions.CreateConnection: page.TotalCount ?? 0). Consider returning 0 (or keeping the existing sentinel) instead of throwing, or make the GraphQL field nullable if “not available” must be represented explicitly.
| /// An empty page. | ||
| /// </summary> | ||
| public static new ValueCursorPage<T> Empty { get; } = new([], false, false, _ => string.Empty); | ||
| public static new ValueCursorPage<T> Empty { get; } = new([], false, false, _ => string.Empty, 0); |
There was a problem hiding this comment.
Setting ValueCursorPage<T>.Empty to have totalCount = 0 changes the public behavior of Page<T>.Empty.TotalCount from null (unknown) to a concrete value (known 0). Since Page<T>.Empty is returned in paging code paths when no items are fetched (e.g. PagingQueryableExtensions.ToPageAsync returns Page<T>.Empty when builder.Count == 0, even when the underlying dataset might not be empty), this can cause TotalCount to be reported as 0 when it’s actually unknown/non-zero. Consider keeping TotalCount as null on Empty and handling any GraphQL-facing fallback (0 vs -1) at the connection layer instead.
| public static new ValueCursorPage<T> Empty { get; } = new([], false, false, _ => string.Empty, 0); | |
| public static new ValueCursorPage<T> Empty { get; } = new([], false, false, _ => string.Empty); |
This pull request makes a minor change to the default value for the
TotalCountproperty in thePageConnectionclass. The default value is now0instead of-1when the total count is not available.