feat(storage): support ifMetagenerationNotMatch - #304
Conversation
Adds an `ifMetagenerationNotMatch` parameter to `Storage.patchBucket`, `Storage.uploadObject` and `Storage.uploadObjectFromString`, resolving the three TODOs that referenced issue googleapis#115. Google Cloud Storage reports an unsatisfied `ifMetagenerationNotMatch` precondition with a "304 Not Modified" status and an empty body, rather than with the "412 Precondition Failed" used by the `*Match` preconditions. That empty body is now translated into a new `NotModifiedException` instead of surfacing as a bare `ServiceException` whose message is "unknown error". Fixes googleapis#115
There was a problem hiding this comment.
Code Review
This pull request adds support for the ifMetagenerationNotMatch precondition parameter in Storage.patchBucket, Storage.uploadObject, and Storage.uploadObjectFromString. It introduces a new NotModifiedException which is thrown when a '304 Not Modified' response is received from Google Cloud Storage, indicating that the precondition was not met. Comprehensive tests have been added to verify this behavior. As there are no review comments, I have no feedback to provide.
|
Maybe the exception decoding logic should live in This seems consistent with the approach taken by other languages e.g. [python with Could you move the |
|
/gcbrun |
Addresses review feedback: - Move the "304 Not Modified" decoding into `ServiceException._fromDecodedResponse`, alongside the other status code mappings, so every API benefits rather than just storage. This drops the `_translateNotModified` wrapper and the storage-local exception class. - A 304 never carries a body, so `fromHttpResponse` now uses a descriptive message for it instead of the generic "unknown error". - Move the `ifMetagenerationNotMatch` tests into the test files for the methods that accept the argument, and cover the status mapping itself in `google_cloud_rpc`'s `exceptions_test.dart`. Also moves the CHANGELOG entry to a new 0.6.4-wip section, since 0.6.3 has been published.
|
Thanks — both done. 1. One thing to flag: a 304 never has a body, so it was hitting the empty-body branch and surfacing as 2. Tests moved into I left |
No, what you did is great!
That's the correct way to do it, thanks! The philosophy of testing in this package is to do integration tests against a GCP test project whenever possible. |
- Move the `ifMetagenerationNotMatch` tests into the existing `google-cloud` groups so they run as integration tests against a real project, matching the testing philosophy of this package, and drop the MockClient-based unit tests. - Drop the storage-specific sentence from `NotModifiedException`'s doc comment in `google_cloud_rpc`, since that package is generic.
|
Thanks, all addressed:
One judgement call: I left the single mapping test in
|
|
/gcbrun |
|
/gcbrun |
brianquinlan
left a comment
There was a problem hiding this comment.
Amazing contribution, thank you so much!
Adds an
ifMetagenerationNotMatchparameter toStorage.patchBucket,Storage.uploadObjectandStorage.uploadObjectFromString, resolving the threeTODOs that referenced this issue.
The failure mode described in #115 no longer applies
The issue reports a
TypeErrorduring JSON deserialization, coming frompackage:googleapis'BucketsResource.patch. That dependency is gone: bothrequest paths (
ServiceClient._makeRequestanduploadFile) now reject anynon-2xx response before deserializing, so a 304 never reaches
jsonDecode.What a 304 does produce today is a bare
ServiceExceptionwithstatusCode: 304and the message"unknown error", which is why this PR stilladds a translation step.
Behaviour
Verified against the storage-testbench: an unsatisfied
ifMetagenerationNotMatchreturns 304 Not Modified with an empty body — on
buckets.patchandobjects.insertalike — rather than the 412 used by the*Matchpreconditions. This PR maps that 304 to a new
NotModifiedException.ServiceExceptionis afinal class, soNotModifiedExceptioncannot extend itand is declared alongside
ChecksumValidationExceptioninstead. If you wouldrather have a generic
304 -> NotModifiedExceptionmapping ingoogle_cloud_rpc(i.e. in Librarian), I am happy to pursue that instead — itwould be reusable across APIs.
Tests
MockClient) covering the query parameter and the 304translation, including a check that a 412 is still reported as a
PreconditionFailedException.storage-testbenchtests asserting the real server behaviour, and that thebucket/object is genuinely left unchanged.
dart format,dart analyze,dart test(272 passing) anddart test -P storage-testbench(75 passing) are all clean.Fixes #115