Skip to content

feat(gax): add resolveResponsePayload helper for response.payload - #9745

Merged
shivanee-p merged 3 commits into
mainfrom
shivaneep-o11y-payload
Oct 30, 2026
Merged

shivanee-p merged 3 commits into
mainfrom
shivaneep-o11y-payload

Conversation

@shivanee-p

Copy link
Copy Markdown
Contributor

Add resolveResponsePayload to errorUtil so LoggerHelper can populate response.payload with the full response serialized as JSON (string payloads are returned as-is). It prefers the raw response gax provides for paginated and long-running calls over the processed response, and returns undefined when there is no response.

@shivanee-p
shivanee-p added this pull request to stack #9746 October 27, 2026 18:13

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the resolveResponsePayload function to serialize response payloads as JSON (or return them as-is if they are already strings), preferring the raw response when available. Unit tests were also added to verify its behavior. The reviewer suggested improving the handling of Uint8Array or Buffer payloads by decoding them to a UTF-8 string first, preventing inefficient serialization and unreadable logs.

@shivanee-p
shivanee-p force-pushed the shivaneep-o11y-payload branch from 002dd72 to 98244b3 Compare October 27, 2026 18:24
@shivanee-p
shivanee-p force-pushed the shivaneep-o11y-payload branch from 98244b3 to 7c3861d Compare October 27, 2026 18:52
@shivanee-p
shivanee-p marked this pull request as ready for review October 27, 2026 23:25
@shivanee-p
shivanee-p requested a review from a team as a code owner October 27, 2026 23:25
@github-actions
github-actions Bot requested a review from quirogas October 27, 2026 23:25
@shivanee-p
shivanee-p force-pushed the shivaneep-o11y-payload branch 2 times, most recently from 5c23589 to b22791a Compare October 28, 2026 16:03

@quirogas quirogas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM! Approved with 2 minor non-blocking nits so this PR is unblocked.

Comment on lines +840 to +850
// Encode binary data as base64. Buffer#toJSON runs before this replacer and
// turns a Buffer into {type: 'Buffer', data: [...]}, so in that case the
// original Buffer is read back from the holder.
const bytes = toBytes(
(val as {type?: unknown}).type === 'Buffer'
? (this as Record<string, unknown>)[key]
: val,
);
if (bytes) {
return encodeBase64(bytes);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Now that safeJsonStringify (lines 840-850) automatically base64-encodes Buffer, Uint8Array, and ArrayBuffer values in its replacer, isBuffer (line 778) and the 20-line cleanMap Buffer-encoding loop in resolveServerExceptionDetails in the same file are redundant; resolveServerExceptionDetails can pass map directly to safeJsonStringify(map).

Comment on lines +888 to +906
export function resolveResponsePayload(
response: unknown,
rawResponse?: unknown,
): string | undefined {
const payload = rawResponse ?? response;
if (payload === undefined || payload === null) {
return undefined;
}
// TODO(security): The payload is returned in full because `response.payload` is defined
// as the raw response, so it can contain sensitive data (e.g. secret values or access
// tokens). Only emit it when logging is explicitly enabled (see `checkLoggingEnabled`),
// and consider redacting known sensitive fields.
if (typeof payload === 'string') {
return payload;
}
// Binary payloads are base64 encoded and, like strings, not wrapped in JSON quotes.
const bytes = toBytes(payload);
return bytes ? encodeBase64(bytes) : safeJsonStringify(payload);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Consider removing the unused rawResponse?: unknown parameter on resolveResponsePayload (response.payload is an L4 error-only attribute in the Milestone 2 Design Doc and never receives paginated/LRO rawResponse), avoiding allocating intermediate Uint8Array and Buffer views in toBytes / encodeBase64 when value is already a Buffer or Uint8Array, and checking Array.isArray((val as {data?: unknown}).data) alongside (val as {type?: unknown}).type === 'Buffer' in safeJsonStringify (line 844) before re-reading this[key].

@shivanee-p
shivanee-p force-pushed the shivaneep-o11y-payload branch from b22791a to 36bbb9b Compare October 29, 2026 16:56
@shivanee-p
shivanee-p force-pushed the shivaneep-o11y-payload branch from 36bbb9b to db3ba99 Compare October 29, 2026 17:49
@shivanee-p
shivanee-p force-pushed the shivaneep-o11y-payload branch 2 times, most recently from 1f82ff2 to 790f978 Compare October 29, 2026 20:11
@shivanee-p
shivanee-p force-pushed the shivaneep-o11y-payload branch 2 times, most recently from 14c124f to 1fad4ea Compare October 30, 2026 02:09
@shivanee-p
shivanee-p force-pushed the shivaneep-o11y-payload branch 2 times, most recently from 1a1433d to ac7adf4 Compare October 30, 2026 02:52
@shivanee-p
shivanee-p force-pushed the shivaneep-o11y-payload branch from ac7adf4 to 0570a43 Compare October 30, 2026 04:21
Base automatically changed from shivaneep-o11y-stacktrace to main October 30, 2026 20:56
Add resolveResponsePayload to errorUtil so LoggerHelper can populate
response.payload with the full response serialized as JSON (string
payloads are returned as-is). It prefers the raw response gax provides
for paginated and long-running calls over the processed response, and
returns undefined when there is no response.

Payloads are not redacted, so a TODO(security) notes they must only be
emitted when logging is explicitly enabled.
Buffers and other binary data (Uint8Array, ArrayBuffer) were serialized one JSON entry per byte, e.g. {"type":"Buffer","data":[...]} or {"0":123,...}, bloating logs. Binary payloads are now base64 encoded, as are binary values nested in a response such as bytes fields. Base64 is how the protobuf JSON mapping represents bytes and matches what REST responses already emit. Uses Buffer when available and protobufjs's pure JavaScript encoder otherwise (e.g. in browsers).
…Stringify tests

resolveResponsePayload passes non-string, non-binary payloads to safeJsonStringify, whose own tests cover circular references and BigInt values. Also drop assertions that repeat the JSON path ([]) or combine two existing cases ((null, null)).
@shivanee-p
shivanee-p force-pushed the shivaneep-o11y-payload branch from 0570a43 to 36e6a90 Compare October 30, 2026 20:56
@shivanee-p
shivanee-p merged commit f4da96e into main Oct 30, 2026
51 checks passed
@shivanee-p
shivanee-p deleted the shivaneep-o11y-payload branch October 30, 2026 23:35
@release-please release-please Bot mentioned this pull request Oct 30, 2026
feywind pushed a commit that referenced this pull request Nov 2, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>google-gax: 6.15.0</summary>

##
[6.15.0](google-gax-v6.14.0...google-gax-v6.15.0)
(2026-11-02)


### Features

* **gax:** Add error attributes for error logging
([#9743](#9743))
([9ad830f](9ad830f))
* **gax:** Add error logging for client requests
([#9756](#9756))
([b0f3dad](b0f3dad))
* **gax:** Add resolveExceptionStacktrace helper for
exception.stacktrace
([#9744](#9744))
([baed8c4](baed8c4))
* **gax:** Add resolveResponsePayload helper for response.payload
([#9745](#9745))
([f4da96e](f4da96e))
* **gax:** Support cancelling API calls via CallOptions.signal
([#9462](#9462))
([4e1f88f](4e1f88f))
</details>

<details><summary>gaxios: 8.3.3</summary>

##
[8.3.3](gaxios-v8.3.2...gaxios-v8.3.3)
(2026-11-02)


### Bug Fixes

* **gaxios:** Enforce maxContentLength on headerless responses in Bun
([#9773](#9773))
([1426695](1426695))
</details>

<details><summary>gapic-tools: 2.2.2</summary>

##
[2.2.2](gapic-tools-v2.2.1...gapic-tools-v2.2.2)
(2026-11-02)


### Bug Fixes

* **tools:** Remove duplicate compileProtos invocation in ESM mode
([#9764](#9764))
([6f475fb](6f475fb))
</details>

<details><summary>pubsub: 6.4.0</summary>

##
[6.4.0](pubsub-v6.3.2...pubsub-v6.4.0)
(2026-11-02)


### Features

* **pubsub:** Add CancellationSharer and HedgingScheduler
([#9464](#9464))
([43ef4dd](43ef4dd))
* **pubsub:** Add enabled option to HedgingOptions (post-merge
adjustments)
([#9654](#9654))
([cdb23f5](cdb23f5))
* **pubsub:** Add HedgingOptions validation and token bucket
([#9463](#9463))
([764347a](764347a))
* **pubsub:** Add OpenTelemetry events and logging for hedged publish
([#9465](#9465))
([8636dba](8636dba))
* **pubsub:** Integrate publish hedging into MessageQueue
([#9466](#9466))
([89fd786](89fd786))
</details>

<details><summary>chat: 0.36.0</summary>

##
[0.36.0](chat-v0.35.0...chat-v0.36.0)
(2026-11-02)


### Features

* Update API sources and regenerate
([#9769](#9769))
([5437a0b](5437a0b))
</details>

<details><summary>ces: 0.11.0</summary>

##
[0.11.0](ces-v0.10.0...ces-v0.11.0)
(2026-11-02)


### Features

* Update API sources and regenerate
([#9769](#9769))
([5437a0b](5437a0b))
</details>

<details><summary>designcenter: 0.1.0</summary>

## 0.1.0 (2026-11-02)


### Features

* **google/cloud/designcenter/v1:** Add google-cloud-designcenter
([#9767](#9767))
([28f6a4b](28f6a4b))
* Update API sources and regenerate
([#9554](#9554))
([8b6837a](8b6837a))
</details>

<details><summary>documentai: 10.3.0</summary>

##
[10.3.0](documentai-v10.2.0...documentai-v10.3.0)
(2026-11-02)


### Features

* Update API sources and regenerate
([#9769](#9769))
([5437a0b](5437a0b))
</details>

<details><summary>geminidataanalytics: 0.15.0</summary>

##
[0.15.0](geminidataanalytics-v0.14.0...geminidataanalytics-v0.15.0)
(2026-11-02)


### Features

* Update API sources and regenerate
([#9769](#9769))
([5437a0b](5437a0b))
</details>

<details><summary>memorystore: 0.13.0</summary>

##
[0.13.0](memorystore-v0.12.0...memorystore-v0.13.0)
(2026-11-02)


### Features

* Update API sources and regenerate
([#9769](#9769))
([5437a0b](5437a0b))
</details>

<details><summary>modelarmor: 0.12.0</summary>

##
[0.12.0](modelarmor-v0.11.0...modelarmor-v0.12.0)
(2026-11-02)


### Features

* Update API sources and regenerate
([#9769](#9769))
([5437a0b](5437a0b))
</details>

<details><summary>network-management: 6.3.0</summary>

##
[6.3.0](network-management-v6.2.0...network-management-v6.3.0)
(2026-11-02)


### Features

* Update API sources and regenerate
([#9769](#9769))
([5437a0b](5437a0b))
</details>

<details><summary>observability: 0.1.1</summary>

##
[0.1.1](observability-v0.1.0...observability-v0.1.1)
(2026-11-02)


### Bug Fixes

* **observability:** Update package.json scripts
([#9770](#9770))
([dcaea88](dcaea88))
</details>

<details><summary>oracledatabase: 0.13.0</summary>

##
[0.13.0](oracledatabase-v0.12.0...oracledatabase-v0.13.0)
(2026-11-02)


### Features

* Update API sources and regenerate
([#9769](#9769))
([5437a0b](5437a0b))
</details>

<details><summary>redis-cluster: 0.19.0</summary>

##
[0.19.0](redis-cluster-v0.18.0...redis-cluster-v0.19.0)
(2026-11-02)


### Features

* Update API sources and regenerate
([#9769](#9769))
([5437a0b](5437a0b))
</details>

<details><summary>sql: 0.31.0</summary>

##
[0.31.0](sql-v0.30.0...sql-v0.31.0)
(2026-11-02)


### Features

* Update API sources and regenerate
([#9769](#9769))
([5437a0b](5437a0b))
</details>

<details><summary>video-transcoder: 5.3.0</summary>

##
[5.3.0](video-transcoder-v5.2.0...video-transcoder-v5.3.0)
(2026-11-02)


### Features

* Update API sources and regenerate
([#9769](#9769))
([5437a0b](5437a0b))
</details>

<details><summary>quota: 0.12.0</summary>

##
[0.12.0](quota-v0.11.0...quota-v0.12.0)
(2026-11-02)


### Features

* Update API sources and regenerate
([#9769](#9769))
([5437a0b](5437a0b))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants