1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
// 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 https://mozilla.org/MPL/2.0/.
use std::ffi::OsString;
use std::fmt::{self, Display};
use std::io;
use std::result;
use rkv::StoreError;
/// A specialized [`Result`] type for this crate's operations.
///
/// This is generally used to avoid writing out [`Error`] directly and
/// is otherwise a direct mapping to [`Result`].
///
/// [`Result`]: https://doc.rust-lang.org/stable/std/result/enum.Result.html
/// [`Error`]: std.struct.Error.html
pub type Result<T, E = Error> = result::Result<T, E>;
/// A list enumerating the categories of errors in this crate.
///
/// [`Error`]: https://doc.rust-lang.org/stable/std/error/trait.Error.html
///
/// This list is intended to grow over time and it is not recommended to
/// exhaustively match against it.
#[derive(Debug)]
#[non_exhaustive]
pub enum ErrorKind {
/// Lifetime conversion failed
Lifetime(i32),
/// IO error
IoError(io::Error),
/// IO error
Rkv(StoreError),
/// JSON error
Json(serde_json::error::Error),
/// TimeUnit conversion failed
TimeUnit(i32),
/// MemoryUnit conversion failed
MemoryUnit(i32),
/// HistogramType conversion failed
HistogramType(i32),
/// [`OsString`] conversion failed
OsString(OsString),
/// Unknown error
Utf8Error,
/// Glean initialization was attempted with an invalid configuration
InvalidConfig,
/// Glean not initialized
NotInitialized,
/// Ping request body size overflowed
PingBodyOverflow(usize),
/// Parsing a UUID from a string failed
UuidError(uuid::Error),
}
/// A specialized [`Error`] type for this crate's operations.
///
/// [`Error`]: https://doc.rust-lang.org/stable/std/error/trait.Error.html
#[derive(Debug)]
pub struct Error {
kind: ErrorKind,
}
impl Error {
/// Returns a new UTF-8 error
///
/// This is exposed in order to expose conversion errors on the FFI layer.
pub fn utf8_error() -> Error {
Error {
kind: ErrorKind::Utf8Error,
}
}
/// Indicates an error that no requested global object is initialized
pub fn not_initialized() -> Error {
Error {
kind: ErrorKind::NotInitialized,
}
}
/// Returns the kind of the current error instance.
pub fn kind(&self) -> &ErrorKind {
&self.kind
}
}
impl std::error::Error for Error {}
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use ErrorKind::*;
match self.kind() {
Lifetime(l) => write!(f, "Lifetime conversion from {} failed", l),
IoError(e) => write!(f, "An I/O error occurred: {}", e),
Rkv(e) => write!(f, "An Rkv error occurred: {}", e),
Json(e) => write!(f, "A JSON error occurred: {}", e),
TimeUnit(t) => write!(f, "TimeUnit conversion from {} failed", t),
MemoryUnit(m) => write!(f, "MemoryUnit conversion from {} failed", m),
HistogramType(h) => write!(f, "HistogramType conversion from {} failed", h),
OsString(s) => write!(f, "OsString conversion from {:?} failed", s),
Utf8Error => write!(f, "Invalid UTF-8 byte sequence in string"),
InvalidConfig => write!(f, "Invalid Glean configuration provided"),
NotInitialized => write!(f, "Global Glean object missing"),
PingBodyOverflow(s) => write!(
f,
"Ping request body size exceeded maximum size allowed: {}kB.",
s / 1024
),
UuidError(e) => write!(f, "Failed to parse UUID: {}", e),
}
}
}
impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Error {
Error { kind }
}
}
impl From<io::Error> for Error {
fn from(error: io::Error) -> Error {
Error {
kind: ErrorKind::IoError(error),
}
}
}
impl From<StoreError> for Error {
fn from(error: StoreError) -> Error {
Error {
kind: ErrorKind::Rkv(error),
}
}
}
impl From<serde_json::error::Error> for Error {
fn from(error: serde_json::error::Error) -> Error {
Error {
kind: ErrorKind::Json(error),
}
}
}
impl From<OsString> for Error {
fn from(error: OsString) -> Error {
Error {
kind: ErrorKind::OsString(error),
}
}
}
/// To satisfy integer conversion done by the macros on the FFI side, we need to be able to turn
/// something infallible into an error.
/// This will never actually be reached, as an integer-to-integer conversion is infallible.
impl From<std::convert::Infallible> for Error {
fn from(_: std::convert::Infallible) -> Error {
unreachable!()
}
}
impl From<uuid::Error> for Error {
fn from(error: uuid::Error) -> Self {
Error {
kind: ErrorKind::UuidError(error),
}
}
}
#[derive(Debug)]
pub enum ClientIdFileError {
/// The file could not be found.
NotFound,
/// Can't access the file due to permissions
PermissionDenied,
/// Another io error happened
IoError(io::Error),
/// Parsing the content into a UUID failed
ParseError(uuid::Error),
}
impl Display for ClientIdFileError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use ClientIdFileError::*;
match self {
NotFound => write!(f, "File not found"),
PermissionDenied => write!(
f,
"The operation lacked the necessary privileges to complete."
),
IoError(e) => write!(f, "IO error occured: {e}"),
ParseError(e) => write!(f, "Parse error occured: {e}"),
}
}
}
impl From<io::Error> for ClientIdFileError {
fn from(error: io::Error) -> Self {
match error.kind() {
io::ErrorKind::NotFound => ClientIdFileError::NotFound,
io::ErrorKind::PermissionDenied => ClientIdFileError::PermissionDenied,
_ => ClientIdFileError::IoError(error),
}
}
}
impl From<uuid::Error> for ClientIdFileError {
fn from(error: uuid::Error) -> Self {
ClientIdFileError::ParseError(error)
}
}