diff options
Diffstat (limited to 'testing/geckodriver/marionette/src/error.rs')
-rw-r--r-- | testing/geckodriver/marionette/src/error.rs | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/testing/geckodriver/marionette/src/error.rs b/testing/geckodriver/marionette/src/error.rs new file mode 100644 index 0000000000..6b05410047 --- /dev/null +++ b/testing/geckodriver/marionette/src/error.rs @@ -0,0 +1,184 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use std::error; +use std::fmt; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize)] +#[serde(untagged)] +pub(crate) enum Error { + Marionette(MarionetteError), +} + +impl Error { + pub fn kind(&self) -> ErrorKind { + match *self { + Error::Marionette(ref err) => err.kind, + } + } +} + +impl fmt::Debug for Error { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::Marionette(ref err) => fmt + .debug_struct("Marionette") + .field("kind", &err.kind) + .field("message", &err.message) + .field("stacktrace", &err.stack.clone()) + .finish(), + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::Marionette(ref err) => write!(fmt, "{}: {}", err.kind, err.message), + } + } +} + +impl error::Error for Error { + fn description(&self) -> &str { + match self { + Error::Marionette(_) => self.kind().as_str(), + } + } +} + +#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize)] +pub struct MarionetteError { + #[serde(rename = "error")] + pub kind: ErrorKind, + #[serde(default = "empty_string")] + pub message: String, + #[serde(rename = "stacktrace", default = "empty_string")] + pub stack: String, +} + +fn empty_string() -> String { + "".to_owned() +} + +impl From<MarionetteError> for Error { + fn from(error: MarionetteError) -> Error { + Error::Marionette(error) + } +} + +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize)] +pub enum ErrorKind { + #[serde(rename = "element click intercepted")] + ElementClickIntercepted, + #[serde(rename = "element not accessible")] + ElementNotAccessible, + #[serde(rename = "element not interactable")] + ElementNotInteractable, + #[serde(rename = "insecure certificate")] + InsecureCertificate, + #[serde(rename = "invalid argument")] + InvalidArgument, + #[serde(rename = "invalid cookie")] + InvalidCookieDomain, + #[serde(rename = "invalid element state")] + InvalidElementState, + #[serde(rename = "invalid selector")] + InvalidSelector, + #[serde(rename = "invalid session id")] + InvalidSessionId, + #[serde(rename = "javascript error")] + JavaScript, + #[serde(rename = "move target out of bounds")] + MoveTargetOutOfBounds, + #[serde(rename = "no such alert")] + NoSuchAlert, + #[serde(rename = "no such element")] + NoSuchElement, + #[serde(rename = "no such frame")] + NoSuchFrame, + #[serde(rename = "no such window")] + NoSuchWindow, + #[serde(rename = "script timeout")] + ScriptTimeout, + #[serde(rename = "session not created")] + SessionNotCreated, + #[serde(rename = "stale element reference")] + StaleElementReference, + #[serde(rename = "timeout")] + Timeout, + #[serde(rename = "unable to set cookie")] + UnableToSetCookie, + #[serde(rename = "unexpected alert open")] + UnexpectedAlertOpen, + #[serde(rename = "unknown command")] + UnknownCommand, + #[serde(rename = "unknown error")] + Unknown, + #[serde(rename = "unsupported operation")] + UnsupportedOperation, + #[serde(rename = "webdriver error")] + WebDriver, +} + +impl ErrorKind { + pub(crate) fn as_str(self) -> &'static str { + use ErrorKind::*; + match self { + ElementClickIntercepted => "element click intercepted", + ElementNotAccessible => "element not accessible", + ElementNotInteractable => "element not interactable", + InsecureCertificate => "insecure certificate", + InvalidArgument => "invalid argument", + InvalidCookieDomain => "invalid cookie", + InvalidElementState => "invalid element state", + InvalidSelector => "invalid selector", + InvalidSessionId => "invalid session id", + JavaScript => "javascript error", + MoveTargetOutOfBounds => "move target out of bounds", + NoSuchAlert => "no such alert", + NoSuchElement => "no such element", + NoSuchFrame => "no such frame", + NoSuchWindow => "no such window", + ScriptTimeout => "script timeout", + SessionNotCreated => "session not created", + StaleElementReference => "stale eelement referencee", + Timeout => "timeout", + UnableToSetCookie => "unable to set cookie", + UnexpectedAlertOpen => "unexpected alert open", + UnknownCommand => "unknown command", + Unknown => "unknown error", + UnsupportedOperation => "unsupported operation", + WebDriver => "webdriver error", + } + } +} + +impl fmt::Display for ErrorKind { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "{}", self.as_str()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::test::assert_ser_de; + use serde_json::json; + + #[test] + fn test_json_error() { + let err = MarionetteError { + kind: ErrorKind::Timeout, + message: "".into(), + stack: "".into(), + }; + assert_ser_de( + &err, + json!({"error": "timeout", "message": "", "stacktrace": ""}), + ); + } +} |