// Copyright 2019-2023 Tauri Programme within The Commons Conservancy // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT use serde::{Serialize, Serializer}; use thiserror::Error; /// All errors that can occur while running the updater. #[derive(Debug, Error)] #[non_exhaustive] pub enum Error { /// Endpoints are not sent. #[error("Updater does not have any endpoints set.")] EmptyEndpoints, /// IO errors. #[error(transparent)] Io(#[from] std::io::Error), /// Semver errors. #[error(transparent)] Semver(#[from] semver::Error), /// Serialization errors. #[error(transparent)] Serialization(#[from] serde_json::Error), /// Could not fetch a valid response from the server. #[error("Could not fetch a valid release JSON from the remote")] ReleaseNotFound, /// Unsupported app architecture. #[error( "Unsupported application architecture, expected one of `x86`, `x86_64`, `arm` or `aarch64`." )] UnsupportedArch, /// Operating system is not supported. #[error("Unsupported OS, expected one of `linux`, `darwin` or `windows`.")] UnsupportedOs, /// Failed to determine updater package extract path #[error("Failed to determine updater package extract path.")] FailedToDetermineExtractPath, /// Url parsing errors. #[error(transparent)] UrlParse(#[from] url::ParseError), /// `reqwest` crate errors. #[error(transparent)] Reqwest(#[from] reqwest::Error), /// The platform was not found in the updater JSON response. #[error("the platform `{0}` was not found in the response `platforms` object")] TargetNotFound(String), /// Neither the platform nor the fallback platform was found in the updater JSON response. #[error("None of the fallback platforms `{0:?}` were found in the response `platforms` object")] TargetsNotFound(Vec), /// Download failed #[error("`{0}`")] Network(String), /// `minisign_verify` errors. #[error(transparent)] Minisign(#[from] minisign_verify::Error), /// `base64` errors. #[error(transparent)] Base64(#[from] base64::DecodeError), /// UTF8 Errors in signature. #[error( "The signature {0} could not be decoded, please check if it is a valid base64 string. The signature must be the contents of the `.sig` file generated by the Tauri bundler, as a string." )] SignatureUtf8(String), #[cfg(all(target_os = "windows", feature = "zip"))] /// `zip` errors. #[error(transparent)] Extract(#[from] zip::result::ZipError), /// No temp dir could be created on the same mount point as the app, which the updater needs /// to move the app aside and the update into place with renames. #[error("temp directory is not on the same mount point as the app")] TempDirNotOnSameMountPoint, /// Installing the update failed, and the app it was replacing could not be moved back to its /// install path either. The previous app was kept at the given path instead. #[error("failed to install the update and to restore the previous app, which was left at {0}")] PreviousAppNotRestored(std::path::PathBuf), /// The downloaded archive does not contain a binary for the current target. #[error("binary for the current target not found in the archive")] BinaryNotFoundInArchive, /// Could not create a temporary directory to store the downloaded update. #[error("failed to create temporary directory")] TempDirNotFound, /// The privilege escalation prompt shown before installing a Linux package /// failed or was dismissed by the user. #[error("Authentication failed or was cancelled")] AuthenticationFailed, /// Installing the downloaded `.deb` package failed. #[error("Failed to install .deb package")] DebInstallFailed, /// The package manager could not install the downloaded Linux package. #[error("Failed to install package")] PackageInstallFailed, /// The downloaded update is not in a format the updater can install on the current platform. #[error("invalid updater binary format")] InvalidUpdaterFormat, /// `http` crate errors. #[error(transparent)] Http(#[from] http::Error), /// A request header value is not valid. #[error(transparent)] InvalidHeaderValue(#[from] http::header::InvalidHeaderValue), /// A request header name is not valid. #[error(transparent)] InvalidHeaderName(#[from] http::header::InvalidHeaderName), /// The release publish date could not be formatted as an RFC 3339 string. #[error("Failed to format date")] FormatDate, /// The configured updater endpoint must use a secure protocol like `https` #[error("The configured updater endpoint must use a secure protocol like `https`.")] InsecureTransportProtocol, /// The version the artifact was signed for does not match the version announced by the /// update endpoint. #[error( "The update was signed for version {signed} but the update endpoint announced version {announced}. The endpoint response may have been tampered with to force installing a different release." )] SignedVersionMismatch { /// The version read from the signature's trusted comment. signed: String, /// The version announced by the update endpoint. announced: String, }, /// `requireSignedVersion` is enabled but the signature does not carry a version. #[error( "The update signature does not specify the version it was signed for, which `requireSignedVersion` requires. Re-sign and re-publish this release, or disable `requireSignedVersion`." )] MissingSignedVersion, /// Tauri errors. #[error(transparent)] Tauri(#[from] tauri::Error), } impl Serialize for Error { fn serialize(&self, serializer: S) -> std::result::Result where S: Serializer, { serializer.serialize_str(self.to_string().as_ref()) } } /// A [`Result`](std::result::Result) alias whose error type is the updater [`Error`](enum@Error). pub type Result = std::result::Result;