From 9ef6e7665b0e2aac4bbd10728979fb6759a30895 Mon Sep 17 00:00:00 2001 From: Fabrice Reix Date: Tue, 22 Sep 2020 13:33:20 +0200 Subject: [PATCH] Improve http error messages --- integration/tests/error_http_connection.err | 2 +- integration/tests/error_http_connection.exit | 2 +- ...hurl.ignore => error_http_connection.hurl} | 0 integration/tests/error_invalid_url.err | 6 ++--- integration/tests/error_invalid_url.hurl | 2 +- src/http/client.rs | 20 ++++++++++------ src/runner/core.rs | 24 ++++++++++++++++++- src/runner/entry.rs | 21 ++++++++++++---- 8 files changed, 58 insertions(+), 19 deletions(-) rename integration/tests/{error_http_connection.hurl.ignore => error_http_connection.hurl} (100%) diff --git a/integration/tests/error_http_connection.err b/integration/tests/error_http_connection.err index e0e60dd61..189ac6e21 100644 --- a/integration/tests/error_http_connection.err +++ b/integration/tests/error_http_connection.err @@ -2,6 +2,6 @@ error: Http Connection --> tests/error_http_connection.hurl:1:5 | 1 | GET http://unknown - | ^^^^^^^^^^^^^^ can not connect to http://unknown/ ("http://unknown/: error trying to connect: failed to lookup address information: Name or service not known") + | ^^^^^^^^^^^^^^ Could not resolve host | diff --git a/integration/tests/error_http_connection.exit b/integration/tests/error_http_connection.exit index 9a7456b54..8148ef7a0 100644 --- a/integration/tests/error_http_connection.exit +++ b/integration/tests/error_http_connection.exit @@ -1,2 +1,2 @@ -2 +3 diff --git a/integration/tests/error_http_connection.hurl.ignore b/integration/tests/error_http_connection.hurl similarity index 100% rename from integration/tests/error_http_connection.hurl.ignore rename to integration/tests/error_http_connection.hurl diff --git a/integration/tests/error_invalid_url.err b/integration/tests/error_invalid_url.err index ad6e1de0c..0e468e225 100644 --- a/integration/tests/error_invalid_url.err +++ b/integration/tests/error_invalid_url.err @@ -1,7 +1,7 @@ -error: Http Connection +error: Invalid url --> tests/error_invalid_url.hurl:1:5 | - 1 | GET unknown - | ^^^^^^^ can not connect to unknown + 1 | GET ??? + | ^^^ Invalid url | diff --git a/integration/tests/error_invalid_url.hurl b/integration/tests/error_invalid_url.hurl index facf65791..1d6cf07df 100644 --- a/integration/tests/error_invalid_url.hurl +++ b/integration/tests/error_invalid_url.hurl @@ -1,2 +1,2 @@ -GET unknown +GET ??? diff --git a/src/http/client.rs b/src/http/client.rs index 2042bc02b..6476d05ba 100644 --- a/src/http/client.rs +++ b/src/http/client.rs @@ -35,6 +35,8 @@ pub enum HttpError { TooManyRedirect, CouldNotParseResponse, SSLCertificate, + InvalidUrl, + Other { description: String, code: u32 }, } #[derive(Debug)] @@ -170,13 +172,17 @@ impl Client { .unwrap(); if let Err(e) = transfer.perform() { - match e.code() { - 5 => return Err(HttpError::CouldNotResolveProxyName), - 6 => return Err(HttpError::CouldNotResolveHost), - 7 => return Err(HttpError::FailToConnect), - 60 => return Err(HttpError::SSLCertificate), - _ => panic!("{:#?}", e), - } + return match e.code() { + 3 => Err(HttpError::InvalidUrl), + 5 => Err(HttpError::CouldNotResolveProxyName), + 6 => Err(HttpError::CouldNotResolveHost), + 7 => Err(HttpError::FailToConnect), + 60 => Err(HttpError::SSLCertificate), + _ => Err(HttpError::Other { + code: e.code(), + description: e.description().to_string(), + }), + }; } } diff --git a/src/runner/core.rs b/src/runner/core.rs index 3505dc624..d3e44c7aa 100644 --- a/src/runner/core.rs +++ b/src/runner/core.rs @@ -114,10 +114,18 @@ pub enum RunnerError { name: String, }, InvalidURL(String), + HttpConnection { url: String, message: String, }, + CouldNotResolveProxyName, + CouldNotResolveHost, + FailToConnect, + TooManyRedirect, + CouldNotParseResponse, + SSLCertificate, + FileReadAccess { value: String, }, @@ -181,6 +189,12 @@ impl FormatError for Error { RunnerError::TemplateVariableNotDefined { .. } => "Undefined Variable".to_string(), RunnerError::VariableNotDefined { .. } => "Undefined Variable".to_string(), RunnerError::HttpConnection { .. } => "Http Connection".to_string(), + RunnerError::CouldNotResolveProxyName => "Http Connection".to_string(), + RunnerError::CouldNotResolveHost => "Http Connection".to_string(), + RunnerError::FailToConnect => "Http Connection".to_string(), + RunnerError::TooManyRedirect => "Http Connection".to_string(), + RunnerError::CouldNotParseResponse => "Http Connection".to_string(), + RunnerError::SSLCertificate => "Http Connection".to_string(), RunnerError::PredicateValue { .. } => "Assert - Predicate Value Failed".to_string(), RunnerError::InvalidRegex {} => "Invalid regex".to_string(), RunnerError::FileReadAccess { .. } => "File ReadAccess".to_string(), @@ -210,7 +224,15 @@ impl FormatError for Error { RunnerError::TemplateVariableNotDefined { name } => { format!("You must set the variable {}", name) } - RunnerError::HttpConnection { url, .. } => format!("can not connect to {}", url), + RunnerError::HttpConnection { url, message } => { + format!("can not connect to {} ({})", url, message) + } + RunnerError::CouldNotResolveProxyName => "Could not resolve proxy name".to_string(), + RunnerError::CouldNotResolveHost => "Could not resolve host".to_string(), + RunnerError::FailToConnect => "Fail to connect".to_string(), + RunnerError::TooManyRedirect => "Too many redirect".to_string(), + RunnerError::CouldNotParseResponse => "Could not parse response".to_string(), + RunnerError::SSLCertificate => "SSl Certificate".to_string(), RunnerError::AssertVersion { actual, .. } => format!("actual value is <{}>", actual), RunnerError::AssertStatus { actual, .. } => format!("actual value is <{}>", actual), RunnerError::PredicateValue(value) => { diff --git a/src/runner/entry.rs b/src/runner/entry.rs index 8633944b4..a75d34402 100644 --- a/src/runner/entry.rs +++ b/src/runner/entry.rs @@ -26,6 +26,7 @@ use crate::http; use super::core::*; use super::core::{Error, RunnerError}; use crate::format::logger::Logger; +use crate::http::HttpError; /// Run an entry with the hurl http client /// @@ -103,7 +104,20 @@ pub fn run( let start = Instant::now(); let http_response = match http_client.execute(&http_request, 0) { Ok(response) => response, - Err(_) => { + Err(http_error) => { + let runner_error = match http_error { + HttpError::CouldNotResolveProxyName => RunnerError::CouldNotResolveProxyName, + HttpError::CouldNotResolveHost => RunnerError::CouldNotResolveHost, + HttpError::FailToConnect => RunnerError::FailToConnect, + HttpError::TooManyRedirect => RunnerError::TooManyRedirect, + HttpError::CouldNotParseResponse => RunnerError::CouldNotParseResponse, + HttpError::SSLCertificate => RunnerError::SSLCertificate, + HttpError::InvalidUrl => RunnerError::InvalidURL(http_request.url.clone()), + HttpError::Other { description, .. } => RunnerError::HttpConnection { + message: description, + url: http_request.url.clone(), + }, + }; return EntryResult { request: Some(http_request.clone()), response: None, @@ -114,10 +128,7 @@ pub fn run( start: entry.clone().request.url.source_info.start, end: entry.clone().request.url.source_info.end, }, - inner: RunnerError::HttpConnection { - message: "".to_string(), - url: http_request.url, - }, + inner: runner_error, assert: false, }], time_in_ms: 0,