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
// 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/.
/// Result values of attempted ping uploads encoded for FFI use.
///
/// In a perfect world this would live in `glean-ffi`,
/// but because we also want to convert from pure integer values to a proper Rust enum
/// using Rust's `From` and `Into` trait, we need to have it in this crate
/// (The coherence rules don't allow to implement an external trait for an external type).
///
/// Due to restrictions of cbindgen they are re-defined in `glean-core/ffi/src/upload.rs`.
///
/// NOTE:
/// THEY MUST BE THE SAME ACROSS BOTH FILES!
pub mod ffi_upload_result {
/// A recoverable error.
pub const UPLOAD_RESULT_RECOVERABLE: u32 = 0x1;
/// An unrecoverable error.
pub const UPLOAD_RESULT_UNRECOVERABLE: u32 = 0x2;
/// A HTTP response code.
///
/// The actual response code is encoded in the lower bits.
pub const UPLOAD_RESULT_HTTP_STATUS: u32 = 0x8000;
}
use ffi_upload_result::*;
/// The result of an attempted ping upload.
#[derive(Debug)]
pub enum UploadResult {
/// A recoverable failure.
///
/// During upload something went wrong,
/// e.g. the network connection failed.
/// The upload should be retried at a later time.
RecoverableFailure,
/// An unrecoverable upload failure.
///
/// A possible cause might be a malformed URL.
UnrecoverableFailure,
/// A HTTP response code.
///
/// This can still indicate an error, depending on the status code.
HttpStatus(u32),
}
impl From<u32> for UploadResult {
fn from(status: u32) -> Self {
match status {
status if (status & UPLOAD_RESULT_HTTP_STATUS) == UPLOAD_RESULT_HTTP_STATUS => {
// Extract the status code from the lower bits.
let http_status = status & !UPLOAD_RESULT_HTTP_STATUS;
UploadResult::HttpStatus(http_status)
}
UPLOAD_RESULT_RECOVERABLE => UploadResult::RecoverableFailure,
UPLOAD_RESULT_UNRECOVERABLE => UploadResult::UnrecoverableFailure,
// Any unknown result code is treated as unrecoverable.
_ => UploadResult::UnrecoverableFailure,
}
}
}
impl UploadResult {
/// Gets the label to be used in recording error counts for upload.
///
/// Returns `None` if the upload finished succesfully.
/// Failures are recorded in the `ping_upload_failure` metric.
pub fn get_label(&self) -> Option<&str> {
match self {
UploadResult::HttpStatus(200..=299) => None,
UploadResult::HttpStatus(400..=499) => Some("status_code_4xx"),
UploadResult::HttpStatus(500..=599) => Some("status_code_5xx"),
UploadResult::HttpStatus(_) => Some("status_code_unknown"),
UploadResult::UnrecoverableFailure => Some("unrecoverable"),
UploadResult::RecoverableFailure => Some("recoverable"),
}
}
}