1#[cfg(unix)]
4use crate::course_refresher::ModeBits;
5use std::{path::PathBuf, string::FromUtf8Error};
6use thiserror::Error;
7use tmc_langs_plugins::compression::ZipError;
8use tmc_langs_util::{JsonError, TomlError, YamlError};
9
10#[derive(Error, Debug)]
12pub enum LangsError {
13 #[error("Failed to create temporary file")]
14 TempFile(#[source] std::io::Error),
15 #[error("Failed to create temporary directory")]
16 TempDir(#[source] std::io::Error),
17 #[error("Invalid parameter key/value: {0}")]
18 InvalidParam(String, #[source] ParamError),
19 #[error("Error compressing data with zstd")]
20 Zstd(#[source] std::io::Error),
21 #[error("Error decoding data with zstd")]
22 ZstdDecode(#[source] std::io::Error),
23 #[error("Error retrieving file handle from tar builder")]
24 TarIntoInner(#[source] std::io::Error),
25 #[error("Error finishing tar")]
26 TarFinish(#[source] std::io::Error),
27 #[error("Error appending path {0} to tar")]
28 TarAppend(PathBuf, #[source] std::io::Error),
29 #[error("Error extracting tar to {0}")]
30 TarExtract(PathBuf, #[source] std::io::Error),
31 #[error("Failed to aquire mutex")]
32 MutexError,
33 #[error("No project directory found in archive during unzip")]
34 NoProjectDirInZip(PathBuf),
35 #[error("Error while writing file to zip")]
36 ZipWrite(#[source] std::io::Error),
37 #[error("Error extracting zip to {0}")]
38 ZipExtract(PathBuf, #[source] ZipError),
39 #[error("Failed to parse file {0}")]
40 SubmissionParse(PathBuf, #[source] Box<Self>),
41 #[error(
42 "Failed to deserialize credentials file at {0}. The file has been removed, please try again"
43 )]
44 DeserializeCredentials(PathBuf, #[source] JsonError),
45 #[error("Failed to deserialize JSON from file at {0}")]
46 DeserializeJson(PathBuf, #[source] JsonError),
47 #[error("Failed to deserialize YAML from file at {0}")]
48 DeserializeYaml(PathBuf, #[source] YamlError),
49 #[error("No local data directory found")]
50 NoLocalDataDir,
51 #[error("No config directory found")]
52 NoConfigDir,
53 #[error("Expected directory at {0} to be empty")]
54 NonEmptyDir(PathBuf),
55 #[error("Directory {0} already exists")]
56 DirectoryExists(PathBuf),
57 #[error("The value for projects-dir must be a string.")]
58 ProjectsDirNotString,
59 #[error("Attempted to move the projects-dir to the directory it's already in")]
60 MovingProjectsDirToItself,
61 #[error("No projects-dir found")]
62 NoProjectsDir,
63 #[error("Exercise in project-config not found")]
64 NoProjectExercise,
65 #[error("Decoded password was not valid UTF-8")]
66 Base64PasswordNotUtf8(#[source] FromUtf8Error),
67 #[error("Failed to decode with base64")]
68 Base64Decode(#[from] base64::DecodeError),
69 #[error("Settings files cannot contain null values")]
70 SettingsCannotContainNull,
71 #[error("The number given was too high: {0}")]
72 SettingNumberTooHigh(serde_json::Number),
73 #[error("Failed to detect exercise language")]
74 NoPlugin,
75 #[error("Invalid Jupyter notebook: {0}")]
76 InvalidNotebook(&'static str),
77 #[error("Invalid path in zip at {zip_path}: {file_path}")]
78 InvalidZipPath {
79 zip_path: PathBuf,
80 file_path: String,
81 },
82 #[error("Failed to find parent directory of {0}")]
83 NoParentDir(PathBuf),
84
85 #[error(
86 "Cache path {0} was invalid. Not a valid UTF-8 string or did not contain a cache version after a dash"
87 )]
88 InvalidCachePath(PathBuf),
89 #[error("Path {0} contained a dash '-' which is currently not allowed")]
90 InvalidDirectory(PathBuf),
91
92 #[error("Server did not return details for local exercise with id {0}")]
93 ExerciseMissingOnServer(u32),
94
95 #[cfg(unix)]
96 #[error("Error changing permissions of {0}")]
97 NixPermissionChange(PathBuf, #[source] nix::Error),
98 #[cfg(unix)]
99 #[error("Invalid chmod flag: {0}")]
100 NixFlag(ModeBits),
101
102 #[error("Failed to canonicalize path {0}")]
103 Canonicalize(PathBuf, #[source] std::io::Error),
104
105 #[error(transparent)]
106 Tmc(#[from] tmc_langs_framework::TmcError),
107 #[error(transparent)]
108 Plugin(#[from] tmc_langs_plugins::PluginError),
109 #[error(transparent)]
110 FileError(#[from] tmc_langs_util::FileError),
111 #[error(transparent)]
114 WalkDir(#[from] walkdir::Error),
115 #[error(transparent)]
116 Zip(#[from] zip::result::ZipError),
117 #[error(transparent)]
118 Yaml(#[from] serde_yaml::Error),
119 #[error(transparent)]
120 TomlSerialize(#[from] toml::ser::Error),
121 #[error(transparent)]
122 TomlDeserialize(#[from] TomlError),
123 #[error(transparent)]
124 Json(#[from] serde_json::Error),
125 #[error(transparent)]
126 Jwt(#[from] jwt::Error),
127 #[error(transparent)]
128 Hmac(#[from] hmac::digest::InvalidLength),
129 #[error(transparent)]
130 TestMyCodeClient(#[from] Box<tmc_testmycode_client::TestMyCodeClientError>),
131 #[error(transparent)]
132 MoocClient(#[from] Box<tmc_mooc_client::MoocClientError>),
133 #[error(transparent)]
134 PersistTempFile(#[from] tempfile::PersistError),
135}
136
137#[derive(Debug, Error)]
139pub enum ParamError {
140 #[error("Parameter key/value was empty")]
141 Empty,
142 #[error("Invalid character found in key/value: {0}")]
143 InvalidChar(char),
144}