use std::ffi::CStr;
use std::fmt;
use vllm_cpp_sys as ffi;
#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum HuggingFaceError {
InvalidInput { message: String },
CacheMiss { message: String },
Incomplete { message: String },
Hub { message: String },
Io { message: String },
}
impl fmt::Display for HuggingFaceError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidInput { message } => write!(f, "invalid Hugging Face model: {message}"),
Self::CacheMiss { message } => write!(f, "Hugging Face cache miss: {message}"),
Self::Incomplete { message } => {
write!(f, "incomplete Hugging Face snapshot: {message}")
}
Self::Hub { message } => write!(f, "Hugging Face Hub failure: {message}"),
Self::Io { message } => write!(f, "Hugging Face cache I/O failure: {message}"),
}
}
}
impl std::error::Error for HuggingFaceError {}
#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum Error {
AbiMismatch { expected: i32, actual: i32 },
InvalidArgument { message: String },
ModelLoad { message: String },
Runtime { message: String },
NativeUnknown { message: String },
UnknownStatus { status: u32, message: String },
InteriorNul { field: &'static str },
PathEncoding,
InvalidUtf8 { field: &'static str },
CallbackPanicked,
LogitsProcessorPanicked,
RequestCallbackThread { operation: &'static str },
InvalidConfiguration { message: String },
Json {
context: &'static str,
message: String,
},
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::AbiMismatch { expected, actual } => {
write!(
f,
"vllm.cpp ABI mismatch: expected {expected}, found {actual}"
)
}
Self::InvalidArgument { message } => write!(f, "invalid argument: {message}"),
Self::ModelLoad { message } => write!(f, "model load failed: {message}"),
Self::Runtime { message } => write!(f, "vllm.cpp runtime failure: {message}"),
Self::NativeUnknown { message } => write!(f, "unknown native failure: {message}"),
Self::UnknownStatus { status, message } => {
write!(f, "unknown native status {status}: {message}")
}
Self::InteriorNul { field } => write!(f, "{field} contains an interior NUL byte"),
Self::PathEncoding => write!(f, "path cannot be represented by the native API"),
Self::InvalidUtf8 { field } => write!(f, "native {field} is not valid UTF-8"),
Self::CallbackPanicked => write!(f, "asynchronous request callback panicked"),
Self::LogitsProcessorPanicked => write!(f, "custom logits processor panicked"),
Self::RequestCallbackThread { operation } => {
write!(
f,
"cannot {operation} a request from its own callback thread"
)
}
Self::InvalidConfiguration { message } => {
write!(f, "invalid configuration: {message}")
}
Self::Json { context, message } => write!(f, "{context}: {message}"),
}
}
}
impl std::error::Error for Error {}
pub(crate) fn status_result(status: ffi::vllm_status) -> Result<(), Error> {
if status == ffi::vllm_status_VLLM_OK {
return Ok(());
}
let message = unsafe {
let pointer = ffi::vllm_last_error();
if pointer.is_null() {
String::new()
} else {
CStr::from_ptr(pointer).to_string_lossy().into_owned()
}
};
let error = match status {
ffi::vllm_status_VLLM_ERR_INVALID_ARGUMENT => Error::InvalidArgument { message },
ffi::vllm_status_VLLM_ERR_MODEL_LOAD => Error::ModelLoad { message },
ffi::vllm_status_VLLM_ERR_RUNTIME => Error::Runtime { message },
ffi::vllm_status_VLLM_ERR_UNKNOWN => Error::NativeUnknown { message },
status => Error::UnknownStatus { status, message },
};
Err(error)
}
pub(crate) fn invalid_configuration(message: impl Into<String>) -> Error {
Error::InvalidConfiguration {
message: message.into(),
}
}