tmc_langs_framework/
error.rs

1//! Contains the TmcError type.
2
3pub use nom_language::error::VerboseError;
4use std::{path::PathBuf, time::Duration};
5pub use subprocess::{ExitStatus, PopenError};
6use thiserror::Error;
7pub use tmc_langs_util::{FileError, YamlError};
8pub use zip::result::ZipError;
9
10// todo: make util error type and move variants there
11#[derive(Error, Debug)]
12pub enum TmcError {
13    #[error("Failed to seek archive")]
14    Seek(#[source] std::io::Error),
15
16    #[error("Failed to hash file")]
17    Hash(#[source] std::io::Error),
18
19    #[error("Failed to read zip file")]
20    ZipRead(#[source] std::io::Error),
21    #[error("Failed to read file inside zip archive with path {0}")]
22    ZipReadFile(PathBuf, #[source] std::io::Error),
23    #[error("Failed to write file at {0} to zip archive")]
24    ZipWrite(PathBuf, #[source] std::io::Error),
25    #[error("Invalid name {0} in zip")]
26    ZipName(String),
27    #[error("Failed to read tar archive")]
28    TarRead(#[source] std::io::Error),
29    #[error("Failed to write tar archive")]
30    TarWrite(#[source] std::io::Error),
31    #[error("Failed to read zstd archive")]
32    ZstdRead(#[source] std::io::Error),
33    #[error("Failed to write zstd archive")]
34    ZstdWrite(#[source] std::io::Error),
35    #[error("Archive size limit exceeded when compressing project (limit: {limit} MB)")]
36    ArchiveSizeLimitExceeded { limit: u32 },
37
38    #[error("Path {0} is not valid UTF-8")]
39    InvalidUtf8(PathBuf),
40
41    #[error("Failed to read line")]
42    ReadLine(#[source] std::io::Error),
43    #[error("Failed to get file metadata")]
44    FileMetadata(#[source] std::io::Error),
45    #[error("Failed to canonicalize path {0}")]
46    Canonicalize(PathBuf, #[source] std::io::Error),
47    #[error("File {0} not in given project root {1}")]
48    FileNotInProject(PathBuf, PathBuf),
49    #[error("Error while parsing available points from {0}")]
50    PointParse(PathBuf, #[source] VerboseError<String>),
51
52    #[error("No project directory found in archive")]
53    NoProjectDirInArchive,
54    #[error("Found project dir in zip, but its path contained invalid UTF-8: {0}")]
55    ProjectDirInvalidUtf8(PathBuf),
56    #[error("Failed to deserialize YAML from file at {0}")]
57    YamlDeserialize(PathBuf, #[source] YamlError),
58
59    #[error("Error in plugin")]
60    Plugin(#[from] Box<dyn std::error::Error + 'static + Send + Sync>),
61
62    #[error("Failed to run command")]
63    Command(#[from] CommandError),
64    #[error("File IO error")]
65    FileError(#[from] FileError),
66    #[error(transparent)]
67    Yaml(#[from] serde_yaml::Error),
68    #[error(transparent)]
69    ZipError(#[from] ZipError),
70    #[error(transparent)]
71    WalkDir(#[from] walkdir::Error),
72}
73
74// == Collection of errors likely to be useful in multiple plugins which can be special cased without needing a plugin's specific error type ==
75/// An error caused by a failed attempt to execute an external command.
76#[derive(Error, Debug)]
77pub enum CommandError {
78    #[error("Failed to execute command: {0}")]
79    Popen(String, #[source] PopenError),
80    #[error(
81        "The executable for command {cmd} could not be found. Please make sure you have installed it correctly."
82    )]
83    NotFound { cmd: String, source: PopenError },
84    #[error("Failed to run command {0}")]
85    FailedToRun(String, #[source] PopenError),
86    #[error("Command {command} exited with status {status:?}")]
87    Failed {
88        command: String,
89        status: ExitStatus,
90        stdout: String,
91        stderr: String,
92    },
93    #[error("Command {command} timed out after {} seconds.", .timeout.as_secs())]
94    TimeOut {
95        command: String,
96        timeout: Duration,
97        stdout: String,
98        stderr: String,
99    },
100    #[error("Failed to terminate command {0}")]
101    Terminate(String, #[source] std::io::Error),
102}