Skip to content

replaced check IsContextError to check stream context error#2102

Merged
asmyasnikov merged 7 commits intomasterfrom
context-error
Apr 28, 2026
Merged

replaced check IsContextError to check stream context error#2102
asmyasnikov merged 7 commits intomasterfrom
context-error

Conversation

@asmyasnikov
Copy link
Copy Markdown
Member

Pull request type

Please check the type of change your PR introduces:

  • Bugfix
  • Feature
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • Documentation content changes
  • Other (please describe):

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Other information

@asmyasnikov asmyasnikov requested a review from Copilot April 28, 2026 14:15
@asmyasnikov
Copy link
Copy Markdown
Member Author

@copilot добавь тесты для изменения в PR
тест должен быть красным до фикса и зеленым после фикса
и добавь строчку в CHANGELOG.md (в начало файла, без указания версии) о сути изменений в PR

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

summary

Inferred base version: v3.135.2
Suggested version: v3.135.3

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.35%. Comparing base (b632353) to head (1f3bcd3).
⚠️ Report is 4 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2102      +/-   ##
==========================================
- Coverage   74.82%   72.35%   -2.47%     
==========================================
  Files         427      427              
  Lines       36902    36902              
==========================================
- Hits        27613    26702     -911     
- Misses       8090     8998     +908     
- Partials     1199     1202       +3     
Flag Coverage Δ
experiment ?
go-1.21.x 72.29% <100.00%> (-0.01%) ⬇️
go-1.26.x 72.31% <100.00%> (-2.49%) ⬇️
integration 57.09% <66.66%> (+0.19%) ⬆️
macOS 46.05% <100.00%> (ø)
ubuntu 72.34% <100.00%> (-2.48%) ⬇️
unit 46.06% <100.00%> (-0.01%) ⬇️
windows 46.04% <100.00%> (+<0.01%) ⬆️
ydb-24.4 56.38% <33.33%> (+0.03%) ⬆️
ydb-edge 56.96% <66.66%> (+0.25%) ⬆️
ydb-latest 56.49% <66.66%> (-0.12%) ⬇️
ydb-nightly ?

Flags with carried forward coverage won't be shown. Click here to find out more.

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates gRPC client stream error handling to detect stream cancellation/deadline via the stream’s context rather than relying on xerrors.IsContextError(err).

Changes:

  • Switched context-error detection in CloseSend, SendMsg, and RecvMsg from xerrors.IsContextError(err) to s.streamCtx.Err() != nil.
  • Added contextual wrapping for errors when the stream context is done.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/conn/grpc_client_stream.go Outdated
Comment thread internal/conn/grpc_client_stream.go Outdated
Comment thread internal/conn/grpc_client_stream.go Outdated
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 28, 2026

@copilot добавь тесты для изменения в PR
тест должен быть красным до фикса и зеленым после фикса
и добавь строчку...

Done in commit f9016a3.

Added StreamContextDoneReturnsNonTransportError tests for CloseSend, SendMsg, and RecvMsg. Each test uses a cancelled streamCtx and a non-gRPC-status error returned by gRPC:

  • RED before fix: old code called xerrors.IsContextError(err) which returns false for a generic error, so it fell through to transport wrapping → IsTransportError = true
  • GREEN after fix: new code checks s.streamCtx.Err() != nil → detects cancelled context and returns a non-transport "stream context is done" error → IsTransportError = false

Also added a CHANGELOG.md entry at the top of the file.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread CHANGELOG.md
@asmyasnikov asmyasnikov merged commit 59b7046 into master Apr 28, 2026
35 of 37 checks passed
@asmyasnikov asmyasnikov deleted the context-error branch April 28, 2026 15:38
Copy link
Copy Markdown

@robot-vibe-db robot-vibe-db Bot left a comment

Choose a reason for hiding this comment

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

AI Review Summary

Verdict: ✅ No critical issues found

The fix is correct — checking s.streamCtx.Err() directly is more reliable than inspecting the gRPC error type via IsContextError, since gRPC may return non-standard errors (e.g. "connection closed") when the stream context is cancelled. The fmt.Errorf + xerrors.Join wrapping preserves both the original gRPC error and the context error in the unwrap chain, so callers using errors.Is, IsContextError, etc. continue to work.

Critical issues

No critical issues found.

Other findings

  • Minor | Medium: The existing ContextError tests (e.g. CloseSend/ContextError at line 151) use context.Background() as streamCtx while having gRPC return context.Canceled. With the new code, s.streamCtx.Err() returns nil, so these tests now fall through to the transport wrapping branch instead of the context-error branch. They still pass because IsContextError traverses the unwrap chain through transportError, but they no longer exercise the intended context detection code path. Consider updating them to use a cancelled stream context. — internal/conn/grpc_client_stream_test.go:164
  • Nit | Low: The new StreamContextDoneReturnsNonTransportError tests assert !IsTransportError and ErrorIs(streamErr), but don't assert IsContextError(err) == true. Since the error wraps context.Canceled via xerrors.Join, this property holds — but asserting it would document the contract and catch future regressions. — internal/conn/grpc_client_stream_test.go:209

This review was generated automatically. Critical issues require attention; other findings are advisory.
If this comment was useful, please give it a 👍 — it helps us improve the review bot.

// When the stream context is done, the error must NOT be wrapped as a
// transport error regardless of what gRPC returned.
require.False(t, xerrors.IsTransportError(err))
require.ErrorIs(t, err, streamErr)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: Nit
Confidence: Low

Consider adding require.True(t, xerrors.IsContextError(err)) here (and in the analogous SendMsg / RecvMsg variants). The returned error wraps context.Canceled via xerrors.Join, so IsContextError should return true — asserting this documents the contract that callers can still detect the error as a context error, not just as "not a transport error".

@@ -173,6 +174,42 @@ func TestGrpcClientStream_CloseSend(t *testing.T) {
require.True(t, xerrors.IsContextError(err))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: Minor
Confidence: Medium

This existing test now exercises a different code path than before. With the old IsContextError(err) check, context.Canceled from gRPC was caught immediately. With the new s.streamCtx.Err() check, context.Background() returns nil, so the code falls through to transport wrapping — the error is now both IsTransportError and IsContextError.

The assertion still passes (the unwrap chain reaches context.Canceled through transportError), but the test no longer validates the context-detection branch. Consider changing streamCtx to a cancelled context so this test exercises the intended path:

cancelledCtx, cancel := context.WithCancel(context.Background())
cancel()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants