feat: classify authorization-required errors (#1056)
This commit is contained in:
parent
3240b6e782
commit
65f05e9924
2 changed files with 142 additions and 0 deletions
|
|
@ -111,6 +111,17 @@ impl ClientInitializeError {
|
|||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns whether client initialization failed because authorization is required.
|
||||
///
|
||||
/// This covers both missing or expired local OAuth authorization and an HTTP
|
||||
/// authorization challenge from the MCP server.
|
||||
pub fn is_authorization_required(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
Self::TransportError { error, .. } if error.is_authorization_required()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to get the next message from the stream
|
||||
|
|
|
|||
|
|
@ -272,6 +272,27 @@ impl DynamicTransportError {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_authorization_required(&self) -> bool {
|
||||
let mut error = Some(self.error.as_ref() as &(dyn std::error::Error + 'static));
|
||||
while let Some(current) = error {
|
||||
#[cfg(feature = "auth")]
|
||||
if matches!(
|
||||
current.downcast_ref::<auth::AuthError>(),
|
||||
Some(auth::AuthError::AuthorizationRequired)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#[cfg(feature = "transport-streamable-http-client")]
|
||||
if current.is::<streamable_http_client::AuthRequiredError>() {
|
||||
return true;
|
||||
}
|
||||
|
||||
error = current.source();
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn downcast<T: Transport<R> + 'static, R: ServiceRole>(self) -> Result<T::Error, Self> {
|
||||
if !self.is::<T, R>() {
|
||||
Err(self)
|
||||
|
|
|
|||
Loading…
Reference in a new issue