Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions examples/crd_derive_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ async fn main() -> Result<()> {
Some(kube::Error::Api(err)) => {
assert_eq!(err.code, 422);
assert_eq!(err.reason, "Invalid");
assert_eq!(err.status, "Failure");
assert!(err.is_failure());
assert!(err.message.contains("clux.dev \"qux\" is invalid"));
assert!(err.message.contains("spec.nonNullable: Required value"));
}
Expand Down Expand Up @@ -271,7 +271,7 @@ async fn main() -> Result<()> {
Some(kube::Error::Api(err)) => {
assert_eq!(err.code, 422);
assert_eq!(err.reason, "Invalid");
assert_eq!(err.status, "Failure");
assert!(err.is_failure());
assert!(err.message.contains("Foo.clux.dev \"baz\" is invalid"));
assert!(err.message.contains("spec.celValidated: Forbidden"));
assert!(err.message.contains("string cannot be illegal"));
Expand All @@ -293,7 +293,7 @@ async fn main() -> Result<()> {
Some(kube::Error::Api(err)) => {
assert_eq!(err.code, 422);
assert_eq!(err.reason, "Invalid");
assert_eq!(err.status, "Failure");
assert!(err.is_failure());
assert!(err.message.contains("Foo.clux.dev \"baz\" is invalid"));
assert!(err.message.contains("spec.celValidated: Invalid value"));
assert!(err.message.contains("failed rule: self != 'not legal'"));
Expand All @@ -316,7 +316,7 @@ async fn main() -> Result<()> {
Some(kube::Error::Api(err)) => {
assert_eq!(err.code, 422);
assert_eq!(err.reason, "Invalid");
assert_eq!(err.status, "Failure");
assert!(err.is_failure());
assert!(err.message.contains("Foo.clux.dev \"baz\" is invalid"));
assert!(err.message.contains("spec.fooSubSpec.field: Invalid value"));
assert!(err.message.contains("failed rule: self != 'not legal'"));
Expand All @@ -339,7 +339,7 @@ async fn main() -> Result<()> {
Some(kube::Error::Api(err)) => {
assert_eq!(err.code, 422);
assert_eq!(err.reason, "Invalid");
assert_eq!(err.status, "Failure");
assert!(err.is_failure());
assert!(err.message.contains("Foo.clux.dev \"baz\" is invalid"));
assert!(err.message.contains("spec.fooSubSpec.field: Invalid value"));
assert!(err.message.contains("some pretty good reason"));
Expand Down Expand Up @@ -375,7 +375,7 @@ async fn main() -> Result<()> {
Some(kube::Error::Api(err)) => {
assert_eq!(err.code, 422);
assert_eq!(err.reason, "Invalid");
assert_eq!(err.status, "Failure");
assert!(err.is_failure());
assert!(err.message.contains("Foo.clux.dev \"baz\" is invalid"));
assert!(err.message.contains("spec.fooSubSpec: Invalid value"));
assert!(err.message.contains("Invalid value: \"object\": is immutable"));
Expand Down
3 changes: 1 addition & 2 deletions examples/secret_syncer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use futures::StreamExt;
use k8s_openapi::api::core::v1::{ConfigMap, Secret};
use kube::{
api::{Api, DeleteParams, ObjectMeta, Patch, PatchParams, Resource},
error::ErrorResponse,
runtime::{
controller::{Action, Controller},
finalizer::{Event, finalizer},
Expand Down Expand Up @@ -66,7 +65,7 @@ async fn cleanup(cm: Arc<ConfigMap>, secrets: &kube::Api<Secret>) -> Result<Acti
.map(|_| ())
.or_else(|err| match err {
// Object is already deleted
kube::Error::Api(ErrorResponse { code: 404, .. }) => Ok(()),
kube::Error::Api(status) if status.is_not_found() => Ok(()),
Comment thread
clux marked this conversation as resolved.
err => Err(err),
})
.map_err(Error::DeleteSecret)?;
Expand Down
8 changes: 3 additions & 5 deletions kube-client/src/api/core_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ use serde::{Serialize, de::DeserializeOwned};
use std::fmt::Debug;

use crate::{Error, Result, api::Api};
use kube_core::{
ErrorResponse, WatchEvent, metadata::PartialObjectMeta, object::ObjectList, params::*, response::Status,
};
use kube_core::{WatchEvent, metadata::PartialObjectMeta, object::ObjectList, params::*, response::Status};

/// PUSH/PUT/POST/GET abstractions
impl<K> Api<K>
Expand Down Expand Up @@ -138,7 +136,7 @@ where
pub async fn get_opt(&self, name: &str) -> Result<Option<K>> {
match self.get(name).await {
Ok(obj) => Ok(Some(obj)),
Err(Error::Api(ErrorResponse { reason, .. })) if &reason == "NotFound" => Ok(None),
Err(Error::Api(status)) if status.is_not_found() => Ok(None),
Err(err) => Err(err),
}
}
Expand Down Expand Up @@ -193,7 +191,7 @@ where
) -> Result<Option<PartialObjectMeta<K>>> {
match self.get_metadata_with(name, gp).await {
Ok(meta) => Ok(Some(meta)),
Err(Error::Api(ErrorResponse { reason, .. })) if &reason == "NotFound" => Ok(None),
Err(Error::Api(status)) if status.is_not_found() => Ok(None),
Err(err) => Err(err),
}
}
Expand Down
6 changes: 3 additions & 3 deletions kube-client/src/api/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ mod tests {

use k8s_openapi::api::core::v1::ConfigMap;
use kube_core::{
ErrorResponse, ObjectMeta,
ObjectMeta,
params::{DeleteParams, PostParams},
};

Expand Down Expand Up @@ -402,7 +402,7 @@ mod tests {
..ConfigMap::default()
});
assert!(
matches!(dbg!(entry2.commit(&PostParams::default()).await), Err(CommitError::Save(Error::Api(ErrorResponse { reason, .. }))) if reason == "AlreadyExists")
matches!(dbg!(entry2.commit(&PostParams::default()).await), Err(CommitError::Save(Error::Api(status))) if status.is_already_exists())
);

// Cleanup
Expand Down Expand Up @@ -473,7 +473,7 @@ mod tests {
.get_or_insert_with(BTreeMap::default)
.insert("key".to_string(), "value3".to_string());
assert!(
matches!(entry2.commit(&PostParams::default()).await, Err(CommitError::Save(Error::Api(ErrorResponse { reason, .. }))) if reason == "Conflict")
matches!(entry2.commit(&PostParams::default()).await, Err(CommitError::Save(Error::Api(status))) if status.is_conflict())
);

// Cleanup
Expand Down
25 changes: 10 additions & 15 deletions kube-client/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use tower::{BoxError, Layer, Service, ServiceExt, buffer::Buffer, util::BoxServi
use tower_http::map_response_body::MapResponseBodyLayer;

pub use self::body::Body;
use crate::{Config, Error, Result, api::WatchEvent, config::Kubeconfig, error::ErrorResponse};
use crate::{Config, Error, Result, api::WatchEvent, config::Kubeconfig};

mod auth;
mod body;
Expand Down Expand Up @@ -364,8 +364,8 @@ impl Client {
}

// Got general error response
if let Ok(e_resp) = serde_json::from_str::<ErrorResponse>(&line) {
return Some(Err(Error::Api(e_resp)));
if let Ok(status) = serde_json::from_str::<Status>(&line) {
return Some(Err(Error::Api(status.boxed())));
}
// Parsing error
Some(Err(Error::SerdeError(e)))
Expand Down Expand Up @@ -572,19 +572,14 @@ async fn handle_api_errors(res: Response<Body>) -> Result<Response<Body>> {
let text = String::from_utf8(body_bytes.to_vec()).map_err(Error::FromUtf8)?;
// Print better debug when things do fail
// trace!("Parsing error: {}", text);
if let Ok(errdata) = serde_json::from_str::<ErrorResponse>(&text) {
tracing::debug!("Unsuccessful: {errdata:?}");
Err(Error::Api(errdata))
if let Ok(status) = serde_json::from_str::<Status>(&text) {
tracing::debug!("Unsuccessful: {status:?}");
Err(Error::Api(status.boxed()))
} else {
tracing::warn!("Unsuccessful data error parse: {}", text);
let error_response = ErrorResponse {
status: status.to_string(),
code: status.as_u16(),
message: format!("{text:?}"),
reason: "Failed to parse error data".into(),
};
tracing::debug!("Unsuccessful: {error_response:?} (reconstruct)");
Err(Error::Api(error_response))
tracing::warn!("Unsuccessful data error parse: {text}");
let status = Status::failure(&text, "Failed to parse error data").with_code(status.as_u16());
tracing::debug!("Unsuccessful: {status:?} (reconstruct)");
Err(Error::Api(status.boxed()))
}
} else {
Ok(res)
Expand Down
4 changes: 2 additions & 2 deletions kube-client/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use http::Uri;
use thiserror::Error;

pub use kube_core::ErrorResponse;
pub use kube_core::Status;

/// Possible errors from the [`Client`](crate::Client)
#[cfg_attr(docsrs, doc(cfg(any(feature = "config", feature = "client"))))]
Expand All @@ -15,7 +15,7 @@ pub enum Error {
///
/// It's quite common to get a `410 Gone` when the `resourceVersion` is too old.
#[error("ApiError: {0} ({0:?})")]
Api(#[source] ErrorResponse),
Api(#[source] Box<Status>),

/// Hyper error
#[cfg(feature = "client")]
Expand Down
18 changes: 0 additions & 18 deletions kube-core/src/error.rs

This file was deleted.

30 changes: 27 additions & 3 deletions kube-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,35 @@ pub mod util;
pub mod watch;
pub use watch::WatchEvent;

mod error;
pub use error::ErrorResponse;

mod version;
pub use version::Version;

pub mod error_boundary;
pub use error_boundary::DeserializeGuard;

/// This type used to be a payload for `kube::Error::Api`. It has been replaced by `Status`.
/// In the interest of backward compatibility, we keep this type definition here as a deprecated alias.
/// `Status` better reflects the Kubernetes API conventions and is more versatile.
/// If you need to migrate your code, simply replace `ErrorResponse` with `Status` and also check
/// helper methods implemented on `Status` for easily identifying common error cases.
///
/// As a reference below is the original definition of this type:
///
/// An error response from the API.
/// #[derive(Error, Deserialize, Serialize, Debug, Clone, Eq, PartialEq)]
/// #[error("{message}: {reason}")]
/// pub struct ErrorResponse {
/// /// The status
/// pub status: String,
/// /// A message about the error
/// #[serde(default)]
/// pub message: String,
/// /// The reason for the error
/// #[serde(default)]
/// pub reason: String,
/// /// The error code
/// pub code: u16,
/// }
///
#[deprecated(since = "3.0.0", note = "use Status instead")]
Comment thread
clux marked this conversation as resolved.
pub type ErrorResponse = Status;
Loading