Bug 1411026 - Propagate Marionette stacks to WebDriver error. r?whimboo draft
authorAndreas Tolfsen <ato@sny.no>
Mon, 23 Oct 2017 21:57:02 +0100
changeset 684971 bf6fa7034b18eec63abaf7fa3b476545ea06f7af
parent 684970 d456df13a28b1c9bf5ae5d12977ba3567ef676d8
child 737014 6a4cae49c14979d4d5aad39006748244fb0f04d4
push id85783
push userbmo:ato@sny.no
push dateMon, 23 Oct 2017 21:00:48 +0000
reviewerswhimboo
bugs1411026
milestone58.0a1
Bug 1411026 - Propagate Marionette stacks to WebDriver error. r?whimboo When a stacktrace is provided from Marionette, use the WebDriverError::new_with_stack constructor to have it propagated as the WebDriver error's stacktrace rather than use the Rust backtrace. This patch also removes MarionetteSession::error_from_string in favour of the new From<String> trait added to ErrorStatus. It also implements an Into<WebDriverError> trait for MarionetteError to ease the conversion. MozReview-Commit-ID: 1z2IGUW5FS2
testing/geckodriver/src/marionette.rs
--- a/testing/geckodriver/src/marionette.rs
+++ b/testing/geckodriver/src/marionette.rs
@@ -658,19 +658,17 @@ impl MarionetteSession {
 
         if resp.id != self.command_id {
             return Err(WebDriverError::new(ErrorStatus::UnknownError,
                                            format!("Marionette responses arrived out of sequence, expected {}, got {}",
                                                    self.command_id, resp.id)));
         }
 
         if let Some(error) = resp.error {
-            let status = self.error_from_string(&error.status);
-
-            return Err(WebDriverError::new(status, error.message));
+            return Err(error.into());
         }
 
         try!(self.update(msg, &resp));
 
         Ok(match msg.command {
             // Everything that doesn't have a response value
             Get(_) | GoBack | GoForward | Refresh | SetTimeouts(_) |
             SwitchToWindow(_) | SwitchToFrame(_) |
@@ -962,48 +960,16 @@ impl MarionetteSession {
                 domain: domain,
                 expiry: expiry,
                 secure: secure,
                 httpOnly: http_only,
             };
             Ok(new_cookie)
         }).collect::<Result<Vec<_>, _>>()
     }
-
-    pub fn error_from_string(&self, error_code: &str) -> ErrorStatus {
-        match error_code {
-            "element click intercepted" => ErrorStatus::ElementClickIntercepted,
-            "element not interactable" | "element not visible" => ErrorStatus::ElementNotInteractable,
-            "element not selectable" => ErrorStatus::ElementNotSelectable,
-            "insecure certificate" => ErrorStatus::InsecureCertificate,
-            "invalid argument" => ErrorStatus::InvalidArgument,
-            "invalid cookie domain" => ErrorStatus::InvalidCookieDomain,
-            "invalid coordinates" | "invalid element coordinates" => ErrorStatus::InvalidCoordinates,
-            "invalid element state" => ErrorStatus::InvalidElementState,
-            "invalid selector" => ErrorStatus::InvalidSelector,
-            "invalid session id" => ErrorStatus::InvalidSessionId,
-            "javascript error" => ErrorStatus::JavascriptError,
-            "move target out of bounds" => ErrorStatus::MoveTargetOutOfBounds,
-            "no such alert" => ErrorStatus::NoSuchAlert,
-            "no such element" => ErrorStatus::NoSuchElement,
-            "no such frame" => ErrorStatus::NoSuchFrame,
-            "no such window" => ErrorStatus::NoSuchWindow,
-            "script timeout" => ErrorStatus::ScriptTimeout,
-            "session not created" => ErrorStatus::SessionNotCreated,
-            "stale element reference" => ErrorStatus::StaleElementReference,
-            "timeout" => ErrorStatus::Timeout,
-            "unable to capture screen" => ErrorStatus::UnableToCaptureScreen,
-            "unable to set cookie" => ErrorStatus::UnableToSetCookie,
-            "unexpected alert open" => ErrorStatus::UnexpectedAlertOpen,
-            "unknown command" => ErrorStatus::UnknownCommand,
-            "unknown error" => ErrorStatus::UnknownError,
-            "unsupported operation" => ErrorStatus::UnsupportedOperation,
-            _ => ErrorStatus::UnknownError,
-        }
-    }
 }
 
 pub struct MarionetteCommand {
     pub id: u64,
     pub name: String,
     pub params: BTreeMap<String, Json>
 }
 
@@ -1294,16 +1260,29 @@ impl ToJson for MarionetteError {
         let mut data = BTreeMap::new();
         data.insert("error".into(), self.code.to_json());
         data.insert("message".into(), self.message.to_json());
         data.insert("stacktrace".into(), self.stacktrace.to_json());
         Json::Object(data)
     }
 }
 
+impl Into<WebDriverError> for MarionetteError {
+    fn into(self) -> WebDriverError {
+        let status = ErrorStatus::from(self.code);
+        let message = self.message;
+
+        if let Some(stack) = self.stacktrace {
+            WebDriverError::new_with_stack(status, message, stack)
+        } else {
+            WebDriverError::new(status, message)
+        }
+    }
+}
+
 fn get_free_port() -> IoResult<u16> {
     TcpListener::bind(&("localhost", 0))
         .and_then(|stream| stream.local_addr())
         .map(|x| x.port())
 }
 
 pub struct MarionetteConnection {
     port: u16,