From 8480f198f7a4986a373e269d445c991201e1024d Mon Sep 17 00:00:00 2001 From: Baptiste Prevot Date: Fri, 19 Apr 2024 15:17:19 +0200 Subject: [PATCH] editoast: core-client: add retry on broken pipes errors --- editoast/openapi.yaml | 20 ++++++++++++++++++++ editoast/src/core/mod.rs | 15 +++++++++++++-- front/public/locales/en/errors.json | 1 + front/public/locales/fr/errors.json | 1 + 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/editoast/openapi.yaml b/editoast/openapi.yaml index 0a524af2d8f..6ad31e87d0d 100644 --- a/editoast/openapi.yaml +++ b/editoast/openapi.yaml @@ -428,6 +428,25 @@ components: - status - message type: object + EditoastCoreErrorBrokenPipe: + properties: + context: + type: object + message: + type: string + status: + enum: + - 500 + type: integer + type: + enum: + - editoast:coreclient:BrokenPipe + type: string + required: + - type + - status + - message + type: object EditoastCoreErrorCannotExtractResponseBody: properties: context: @@ -671,6 +690,7 @@ components: - $ref: '#/components/schemas/EditoastAutoFixesEditoastErrorMissingErrorObject' - $ref: '#/components/schemas/EditoastCacheOperationErrorDuplicateIdsProvided' - $ref: '#/components/schemas/EditoastCacheOperationErrorObjectNotFound' + - $ref: '#/components/schemas/EditoastCoreErrorBrokenPipe' - $ref: '#/components/schemas/EditoastCoreErrorCannotExtractResponseBody' - $ref: '#/components/schemas/EditoastCoreErrorConnectionClosedBeforeMessageCompleted' - $ref: '#/components/schemas/EditoastCoreErrorConnectionResetByPeer' diff --git a/editoast/src/core/mod.rs b/editoast/src/core/mod.rs index 50398aed7bc..34b65f501ad 100644 --- a/editoast/src/core/mod.rs +++ b/editoast/src/core/mod.rs @@ -115,10 +115,12 @@ impl CoreClient { match request.send().await.map_err(Into::::into) { // This error occurs quite often in the CI. // It's linked to this issue /~https://github.com/hyperium/hyper/issues/2136. - // This is why we retry the request here + // This is why we retry the request here. + // We also retry on broken pipe. Err( CoreError::ConnectionResetByPeer - | CoreError::ConnectionClosedBeforeMessageCompleted, + | CoreError::ConnectionClosedBeforeMessageCompleted + | CoreError::BrokenPipe, ) if i_try < MAX_RETRIES => { i_try += 1; info!("Core request '{}: {}': Connection closed before message completed. Retry [{}/{}]", method, path, i_try, MAX_RETRIES); @@ -314,6 +316,9 @@ enum CoreError { #[error("Core connection reset by peer. Should retry.")] #[editoast_error(status = 500)] ConnectionResetByPeer, + #[error("Core connection broken. Should retry.")] + #[editoast_error(status = 500)] + BrokenPipe, #[cfg(test)] #[error("The mocked response had no body configured - check out StubResponseBuilder::body if this is unexpected")] @@ -364,6 +369,12 @@ impl From for CoreError { if value.to_string().contains("Connection reset by peer") { return Self::ConnectionResetByPeer; } + if value + .to_string() + .contains("error writing a body to connection: Broken pipe") + { + return Self::BrokenPipe; + } // Convert the reqwest error Self::GenericCoreError { diff --git a/front/public/locales/en/errors.json b/front/public/locales/en/errors.json index f404db82715..00c80c4cecb 100644 --- a/front/public/locales/en/errors.json +++ b/front/public/locales/en/errors.json @@ -26,6 +26,7 @@ "ObjectNotFound": "{{obj_type}} {{obj_id}} could not be found everywhere in the infrastructure cache" }, "coreclient": { + "BrokenPipe": "Core connection broken pipe. Should retry.", "CannotExtractResponseBody": "Cannot extract Core response body: {{msg}}", "ConnectionClosedBeforeMessageCompleted": "Core connection closed before message completed. Should retry.", "ConnectionResetByPeer": "Core connection reset by peer. Should retry.", diff --git a/front/public/locales/fr/errors.json b/front/public/locales/fr/errors.json index 29c0eca7cf7..6ace13fd9ae 100644 --- a/front/public/locales/fr/errors.json +++ b/front/public/locales/fr/errors.json @@ -26,6 +26,7 @@ "ObjectNotFound": "{{obj_type}} {{obj_id}} n'a pu être trouvé nulle part dans le cache de l'infrastructure" }, "coreclient": { + "BrokenPipe": "Core: connexion interrompue. Nouvelle tentative.", "CannotExtractResponseBody": "Core: Impossible d'extraire le corps de la réponse : {{msg}}", "ConnectionClosedBeforeMessageCompleted": "Core: connexion fermée avant la fin du message. Nouvelle tentative.", "ConnectionResetByPeer": "Core: réinitialisation de la connexion. Nouvelle tentative.",