use pragma_jobs::JobError;
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum GraphError {
#[error("dependency cycle: {}", tasks.join(" -> "))]
#[non_exhaustive]
Cycle {
tasks: Vec<String>,
},
#[error("tasks `{a}` and `{b}` conflict on resource `{resource}` without explicit ordering")]
#[non_exhaustive]
AmbiguousOrder {
a: String,
b: String,
resource: String,
},
#[error("task `{task}` depends on unknown task `{missing}`")]
#[non_exhaustive]
UnknownDependency {
task: String,
missing: String,
},
#[error("task `{task}` is registered twice")]
#[non_exhaustive]
DuplicateTask {
task: String,
},
#[error("frame graph with {tasks} tasks is too large: {reason}")]
#[non_exhaustive]
TooLarge {
tasks: usize,
reason: &'static str,
},
#[error("task `{task}` needs resource `{resource}`, which is missing")]
#[non_exhaustive]
MissingResource {
task: String,
resource: String,
},
#[error("task `{task}` accessed `{resource}` for {access} without declaring it")]
#[non_exhaustive]
UndeclaredAccess {
task: String,
resource: String,
access: &'static str,
},
#[error("task `{task}`: resource `{resource}` is already borrowed")]
#[non_exhaustive]
BorrowConflict {
task: String,
resource: String,
},
#[error("task `{task}` failed: {message}")]
#[non_exhaustive]
TaskFailed {
task: String,
message: String,
},
#[error("task `{task}` panicked: {message}")]
#[non_exhaustive]
TaskPanicked {
task: String,
message: String,
},
#[error(transparent)]
Job(#[from] JobError),
}
impl GraphError {
pub(crate) fn panicked(task: &str, payload: &(dyn std::any::Any + Send)) -> Self {
let message = if let Some(s) = payload.downcast_ref::<&str>() {
(*s).to_owned()
} else if let Some(s) = payload.downcast_ref::<String>() {
s.clone()
} else {
String::from("<non-string panic payload>")
};
Self::TaskPanicked {
task: task.to_owned(),
message,
}
}
}