From 875d7d8e6ef0803ae1c331dbf76b1981b0caeb15 Mon Sep 17 00:00:00 2001 From: zah Date: Sat, 14 May 2022 11:08:13 +0300 Subject: [PATCH] Tentative fix for the HTTP client connection state assertion failures (#272) * Tentative fix for the HTTP client connection state assertion failures I've traced the problem to a HTTP connection being closed while there are outstanding requests that still go through the motions (the crash occurs when a requests reaches its `finish` processing step, but it was already put in a Closed state by the connection that owns it). * Use distinct error exception instead of cancellation error. Co-authored-by: cheatfate --- chronos/apps/http/httpclient.nim | 5 +++++ chronos/apps/http/httpcommon.nim | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/chronos/apps/http/httpclient.nim b/chronos/apps/http/httpclient.nim index 20d9f1b..f4fa2d5 100644 --- a/chronos/apps/http/httpclient.nim +++ b/chronos/apps/http/httpclient.nim @@ -1073,6 +1073,11 @@ proc finish*(request: HttpClientRequestRef): Future[HttpClientResponseRef] {. ## Finish sending request and receive response. doAssert(not(isNil(request.connection)), "Request missing connection instance") + if request.connection.state in {HttpClientConnectionState.Closing, + HttpClientConnectionState.Closed}: + let e = newHttpUseClosedError() + request.setError(e) + raise e doAssert(request.state == HttpReqRespState.Open, "Request's state is " & $request.state) doAssert(request.connection.state == diff --git a/chronos/apps/http/httpcommon.nim b/chronos/apps/http/httpcommon.nim index d039bf1..3f01e67 100644 --- a/chronos/apps/http/httpcommon.nim +++ b/chronos/apps/http/httpcommon.nim @@ -53,6 +53,7 @@ type HttpProtocolError* = object of HttpError HttpRedirectError* = object of HttpError HttpAddressError* = object of HttpError + HttpUseClosedError* = object of HttpError KeyValueTuple* = tuple key: string @@ -111,6 +112,9 @@ template newHttpReadError*(message: string): ref HttpReadError = template newHttpWriteError*(message: string): ref HttpWriteError = newException(HttpWriteError, message) +template newHttpUseClosedError*(): ref HttpUseClosedError = + newException(HttpUseClosedError, "Connection was already closed") + iterator queryParams*(query: string, flags: set[QueryParamsFlag] = {}): KeyValueTuple {. raises: [Defect].} =