Fix: return HTTP 409 for duplicate datasets and jobs#440
Open
shollands-sc wants to merge 1 commit into
Open
Conversation
When creating a dataset or job that already exists, the emulator returns HTTP 500 (InternalServerError) instead of HTTP 409 (Conflict). This causes the BigQuery Python client to retry with exponential backoff for up to 600 seconds, since it treats 500 as transient. The exists_ok=True parameter also fails to suppress the error because it only checks for 409. This fix follows the existing ErrDuplicatedTable pattern already in the codebase: sentinel errors in the metadata package, checked with errors.Is in ServeHTTP, mapped to errDuplicate() for the HTTP response. Handle() method signatures are unchanged, addressing the feedback on goccy#184. Fixes goccy#256 Supersedes goccy#184 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When creating a dataset or job that already exists, the emulator returns HTTP 500 (InternalServerError) instead of the correct HTTP 409 (Conflict). This causes two problems for BigQuery client libraries:
exists_ok=Truebypass: The Python client'sexists_okparameter only suppresses 409 errors, so the 500 bypasses it entirelyApproach
This follows the existing
ErrDuplicatedTablepattern already in the codebase (internal/metadata/dataset.go+server/handler.go:2609):ErrDuplicatedDatasetandErrDuplicatedJobsentinel errors ininternal/metadata/project.go%winAddDataset/AddJobforerrors.Issupporterrors.IsinServeHTTPand useerrDuplicate()for the HTTP responseAddressing feedback from #184
Per @goccy's review comments on #184:
errDuplicatefunction in error.go" — Done. We use the existingerrDuplicate()in the handlers, consistent with howErrDuplicatedTableis already handled*ServerErrortype" — Done.Handle()method signatures are unchanged; theerrors.Ischeck happens inServeHTTPChanges
internal/metadata/project.goErrDuplicatedDataset,ErrDuplicatedJobsentinels; wrap with%wserver/handler.godatasetsInsertHandler.ServeHTTPandjobsInsertHandler.ServeHTTPcheckerrors.Is→errDuplicate()server/server_test.goTestDuplicateDataset(mirrors existingTestDuplicateTable)Fixes #256
Supersedes #184
Test plan
TestDuplicateDataset— verifies HTTP 409 on duplicate dataset creationTestDuplicateTable— existing test still passes (no regression)TestDataset— existing test still passes (no regression)go build ./...— compiles cleanly