This is an automated email from the ASF dual-hosted git repository. Cole-Greer pushed a commit to branch GLVBehaviouralAlignment in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 5378f5c78f08ab2f37ee0955d1b787e86d389fcf Author: Cole Greer <[email protected]> AuthorDate: Thu Jul 16 15:40:44 2026 -0700 Revert JS transport-error wrapping; skip no-response timeout test Drop the ResponseError wrapping around fetch/response failures in Connection#makeHttpRequest and #handleResponse, reverting to raw transport errors bubbling up unwrapped. Skip should timeout when server never responds: readTimeoutMillis maps only to undici's bodyTimeout, which doesn't start ticking until response parsing begins, so it never fires for a server that sends nothing at all. --- .../GraphBinaryStreamResponseReaderTest.java | 2 +- .../gremlin-javascript/lib/driver/connection.ts | 39 ++++++---------------- .../test/integration/client-behavior-tests.js | 25 ++++---------- 3 files changed, 17 insertions(+), 49 deletions(-) diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/handler/GraphBinaryStreamResponseReaderTest.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/handler/GraphBinaryStreamResponseReaderTest.java index 2b657a1f9b..06adcbe80d 100644 --- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/handler/GraphBinaryStreamResponseReaderTest.java +++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/handler/GraphBinaryStreamResponseReaderTest.java @@ -225,7 +225,7 @@ public class GraphBinaryStreamResponseReaderTest { } @Test - public void shouldProduceClearErrorOnEmptyBody() throws Exception { + public void shouldProduceClearErrorOnEmptyBody() { final ResultSet rs = new ResultSet(executor, RequestMessage.build("g.V()").create(), null); final AtomicReference<ResultSet> pending = new AtomicReference<>(rs); diff --git a/gremlin-js/gremlin-javascript/lib/driver/connection.ts b/gremlin-js/gremlin-javascript/lib/driver/connection.ts index 47407cbcc5..fc4e1c0bda 100644 --- a/gremlin-js/gremlin-javascript/lib/driver/connection.ts +++ b/gremlin-js/gremlin-javascript/lib/driver/connection.ts @@ -322,39 +322,20 @@ export default class Connection extends EventEmitter { this._log('debug', `Sending ${httpRequest.method} request to ${httpRequest.url}`); - try { - return await httpFetch.fetch(httpRequest.url, { - method: httpRequest.method, - headers: httpRequest.headers, - body: httpRequest.body, - signal, - // Node only: the undici dispatcher carries the connection-pool options. In the browser - // it is undefined and the field is omitted, letting the user agent manage the transport. - ...(this._dispatcher ? { dispatcher: this._dispatcher } : {}), - } as RequestInit); - } catch (err: any) { - const e = new ResponseError( - 'Connection to server closed unexpectedly. Ensure that the server is still reachable and the connection has not been closed by the server or a network device.', - { code: 599, message: err.message || 'Connection failed' }, - ); - e.cause = err; - throw e; - } + return httpFetch.fetch(httpRequest.url, { + method: httpRequest.method, + headers: httpRequest.headers, + body: httpRequest.body, + signal, + // Node only: the undici dispatcher carries the connection-pool options. In the browser + // it is undefined and the field is omitted, letting the user agent manage the transport. + ...(this._dispatcher ? { dispatcher: this._dispatcher } : {}), + } as RequestInit); } async #handleResponse(response: Response) { - let buffer: Buffer; - try { - buffer = Buffer.from(await response.arrayBuffer()); - } catch (err: any) { - const e = new ResponseError( - 'Connection to server closed unexpectedly. Ensure that the server is still reachable and the connection has not been closed by the server or a network device.', - { code: 599, message: err.message || 'Connection failed' }, - ); - e.cause = err; - throw e; - } const contentType = response.headers.get("Content-Type"); + const buffer = Buffer.from(await response.arrayBuffer()); const reader = this.#getReaderForContentType(contentType); if (!response.ok) { diff --git a/gremlin-js/gremlin-javascript/test/integration/client-behavior-tests.js b/gremlin-js/gremlin-javascript/test/integration/client-behavior-tests.js index a8f9f3de50..0124c4e9cf 100644 --- a/gremlin-js/gremlin-javascript/test/integration/client-behavior-tests.js +++ b/gremlin-js/gremlin-javascript/test/integration/client-behavior-tests.js @@ -67,11 +67,7 @@ describe('Client Behavior', function () { }); it('should handle connection close before response and recover', async function () { - await assert.rejects(client.submit(GREMLIN_CLOSE_CONNECTION), (err) => { - assert.strictEqual(err.name, 'ResponseError'); - assert.match(err.message, /Connection to server closed unexpectedly/); - return true; - }); + await assert.rejects(client.submit(GREMLIN_CLOSE_CONNECTION), /fetch failed/); const result = await client.submit(GREMLIN_SINGLE_VERTEX); assert.strictEqual(result.length, 1); }); @@ -97,11 +93,7 @@ describe('Client Behavior', function () { }); it('should handle partial content close and recover', async function () { - await assert.rejects(client.submit(GREMLIN_PARTIAL_CONTENT_CLOSE), (err) => { - assert.strictEqual(err.name, 'ResponseError'); - assert.match(err.message, /Connection to server closed unexpectedly/); - return true; - }); + await assert.rejects(client.submit(GREMLIN_PARTIAL_CONTENT_CLOSE), /terminated/); const result = await client.submit(GREMLIN_SINGLE_VERTEX); assert.strictEqual(result.length, 1); }); @@ -125,18 +117,13 @@ describe('Client Behavior', function () { assert.ok(result.length > 0); }); - it('should timeout when server never responds', async function () { + // readTimeoutMillis doesn't start ticking until response parsing + // begins, so it never fires for a server that sends nothing at all. + it.skip('should timeout when server never responds', async function () { this.timeout(5000); const shortTimeoutClient = createClient({ readTimeoutMillis: 1000 }); try { - await assert.rejects( - shortTimeoutClient.submit(GREMLIN_NO_RESPONSE), - (err) => { - assert.match(err.message, /closed unexpectedly/i); - assert.strictEqual(err.name, 'ResponseError'); - return true; - }, - ); + await assert.rejects(shortTimeoutClient.submit(GREMLIN_NO_RESPONSE)); const result = await shortTimeoutClient.submit(GREMLIN_SINGLE_VERTEX); assert.strictEqual(result.length, 1); } finally {
