Extract plugin manager errors and box realtime handoff routing (#57294)

## What changed

- Move plugin install and uninstall errors and telemetry classification helpers into `codex-rs/core-plugins/src/manager_errors.rs`, preserving the existing public re-exports and error classifications.
- Box the realtime text routing future to bound the handoff future's size while retaining the admission permit across the await.

GitOrigin-RevId: ccf0c3bb93a8c69a0a618b96cd1525da87003176
This commit is contained in:
Anthony Tafoya
2026-10-26 22:23:59 +00:00
committed by copyberry
parent 126a0ee92e
commit 62f7f3418f
3 changed files with 152 additions and 138 deletions
+8 -137
View File
@@ -1,3 +1,11 @@
#[path = "manager_errors.rs"]
mod errors;
pub use errors::PluginInstallError;
pub use errors::PluginUninstallError;
use errors::marketplace_error_sub_error_type;
use errors::marketplace_error_type;
use errors::plugin_install_error_type;
#[path = "remote_mutations.rs"]
mod remote_mutations;
pub use remote_mutations::RemotePluginInstallOutcome;
@@ -74,7 +82,6 @@ use crate::remote::RemotePluginMaterialization;
use crate::remote::RemotePluginScope;
use crate::remote::RemotePluginServiceConfig;
use crate::remote_legacy::RemotePluginFetchError;
use crate::remote_legacy::RemotePluginMutationError;
use crate::remote_plugin_id_resolver::RemoteInstalledPluginsSnapshot;
use crate::remote_plugin_id_resolver::RemotePluginIdResolver;
use crate::remote_plugin_id_resolver::persisted_remote_plugin_id_for_installation;
@@ -87,7 +94,6 @@ use crate::startup_sync::sync_openai_plugins_repo;
use crate::store::PluginInstallResult as StorePluginInstallResult;
use crate::store::PluginStore;
use crate::store::PluginStoreError;
use crate::store::error_context_sub_error_type;
use crate::tool_suggest_metadata::ToolSuggestMetadataCache;
use codex_analytics::AnalyticsEventsClient;
use codex_analytics::PluginInstallSource;
@@ -3778,141 +3784,6 @@ pub(crate) fn remote_plugin_install_required_description(
)
}
#[derive(Debug, thiserror::Error)]
pub enum PluginInstallError {
#[error("{0}")]
Marketplace(#[from] MarketplaceError),
#[error("{0}")]
Remote(#[from] RemotePluginMutationError),
#[error("{0}")]
Store(#[from] PluginStoreError),
#[error("{0}")]
Config(#[from] anyhow::Error),
#[error("failed to join plugin install task: {0}")]
Join(#[from] tokio::task::JoinError),
}
impl PluginInstallError {
fn join(source: tokio::task::JoinError) -> Self {
Self::Join(source)
}
pub fn is_invalid_request(&self) -> bool {
matches!(
self,
Self::Marketplace(
MarketplaceError::MarketplaceNotFound { .. }
| MarketplaceError::InvalidMarketplaceFile { .. }
| MarketplaceError::PluginNotFound { .. }
| MarketplaceError::PluginNotAvailable { .. }
| MarketplaceError::InvalidPlugin(_)
) | Self::Store(PluginStoreError::Invalid(_))
)
}
pub fn sub_error_type(&self) -> Option<String> {
match self {
Self::Marketplace(err) => marketplace_error_sub_error_type(err),
Self::Remote(err) => err.sub_error_type(),
Self::Store(err) => err.sub_error_type(),
Self::Config(_) => Some("failed_to_enable_plugin".to_string()),
Self::Join(_) => Some("plugin_install_task_failed".to_string()),
}
}
}
fn plugin_install_error_type(err: &PluginInstallError) -> &'static str {
match err {
PluginInstallError::Marketplace(err) => marketplace_error_type(err),
PluginInstallError::Remote(err) => remote_plugin_mutation_error_type(err),
PluginInstallError::Store(err) => plugin_store_error_type(err),
PluginInstallError::Config(_) => "config",
PluginInstallError::Join(_) => "join",
}
}
fn marketplace_error_type(err: &MarketplaceError) -> &'static str {
match err {
MarketplaceError::Io { .. } => "marketplace_io",
MarketplaceError::MarketplaceNotFound { .. } => "marketplace_not_found",
MarketplaceError::InvalidMarketplaceFile { .. } => "invalid_marketplace_file",
MarketplaceError::PluginNotFound { .. } => "plugin_not_found",
MarketplaceError::PluginNotAvailable { .. } => "plugin_not_available",
MarketplaceError::PluginsDisabled => "plugins_disabled",
MarketplaceError::InvalidPlugin(_) => "invalid_plugin",
}
}
fn marketplace_error_sub_error_type(err: &MarketplaceError) -> Option<String> {
match err {
MarketplaceError::Io { context, .. } => Some(error_context_sub_error_type(context)),
MarketplaceError::MarketplaceNotFound { .. }
| MarketplaceError::InvalidMarketplaceFile { .. }
| MarketplaceError::PluginNotFound { .. }
| MarketplaceError::PluginNotAvailable { .. }
| MarketplaceError::PluginsDisabled
| MarketplaceError::InvalidPlugin(_) => None,
}
}
fn remote_plugin_mutation_error_type(err: &RemotePluginMutationError) -> &'static str {
match err {
RemotePluginMutationError::AuthRequired => "remote_mutation_auth_required",
RemotePluginMutationError::UnsupportedAuthMode => "remote_mutation_unsupported_auth_mode",
RemotePluginMutationError::AuthToken(_) => "remote_mutation_auth_token",
RemotePluginMutationError::InvalidBaseUrl(_) => "remote_mutation_invalid_base_url",
RemotePluginMutationError::InvalidBaseUrlPath => "remote_mutation_invalid_base_url_path",
RemotePluginMutationError::Request { .. } => "remote_mutation_request",
RemotePluginMutationError::UnexpectedStatus { .. } => "remote_mutation_unexpected_status",
RemotePluginMutationError::Decode { .. } => "remote_mutation_decode",
RemotePluginMutationError::UnexpectedPluginId { .. } => {
"remote_mutation_unexpected_plugin_id"
}
RemotePluginMutationError::UnexpectedEnabledState { .. } => {
"remote_mutation_unexpected_enabled_state"
}
}
}
fn plugin_store_error_type(err: &PluginStoreError) -> &'static str {
match err {
PluginStoreError::Io { .. } => "store_io",
PluginStoreError::Invalid(_) => "store_invalid",
}
}
#[derive(Debug, thiserror::Error)]
pub enum PluginUninstallError {
#[error("{0}")]
InvalidPluginId(#[from] PluginIdError),
#[error("{0}")]
Remote(#[from] RemotePluginMutationError),
#[error("{0}")]
Store(#[from] PluginStoreError),
#[error("{0}")]
Config(#[from] anyhow::Error),
#[error("failed to join plugin uninstall task: {0}")]
Join(#[from] tokio::task::JoinError),
}
impl PluginUninstallError {
fn join(source: tokio::task::JoinError) -> Self {
Self::Join(source)
}
pub fn is_invalid_request(&self) -> bool {
matches!(self, Self::InvalidPluginId(_))
}
}
#[cfg(test)]
#[path = "manager_tests.rs"]
mod tests;
+142
View File
@@ -0,0 +1,142 @@
//! Plugin mutation errors and their stable telemetry classifications.
use crate::marketplace::MarketplaceError;
use crate::remote_legacy::RemotePluginMutationError;
use crate::store::PluginStoreError;
use crate::store::error_context_sub_error_type;
use codex_plugin::PluginIdError;
#[derive(Debug, thiserror::Error)]
pub enum PluginInstallError {
#[error("{0}")]
Marketplace(#[from] MarketplaceError),
#[error("{0}")]
Remote(#[from] RemotePluginMutationError),
#[error("{0}")]
Store(#[from] PluginStoreError),
#[error("{0}")]
Config(#[from] anyhow::Error),
#[error("failed to join plugin install task: {0}")]
Join(#[from] tokio::task::JoinError),
}
impl PluginInstallError {
pub(super) fn join(source: tokio::task::JoinError) -> Self {
Self::Join(source)
}
pub fn is_invalid_request(&self) -> bool {
matches!(
self,
Self::Marketplace(
MarketplaceError::MarketplaceNotFound { .. }
| MarketplaceError::InvalidMarketplaceFile { .. }
| MarketplaceError::PluginNotFound { .. }
| MarketplaceError::PluginNotAvailable { .. }
| MarketplaceError::InvalidPlugin(_)
) | Self::Store(PluginStoreError::Invalid(_))
)
}
pub fn sub_error_type(&self) -> Option<String> {
match self {
Self::Marketplace(err) => marketplace_error_sub_error_type(err),
Self::Remote(err) => err.sub_error_type(),
Self::Store(err) => err.sub_error_type(),
Self::Config(_) => Some("failed_to_enable_plugin".to_string()),
Self::Join(_) => Some("plugin_install_task_failed".to_string()),
}
}
}
pub(super) fn plugin_install_error_type(err: &PluginInstallError) -> &'static str {
match err {
PluginInstallError::Marketplace(err) => marketplace_error_type(err),
PluginInstallError::Remote(err) => remote_plugin_mutation_error_type(err),
PluginInstallError::Store(err) => plugin_store_error_type(err),
PluginInstallError::Config(_) => "config",
PluginInstallError::Join(_) => "join",
}
}
pub(super) fn marketplace_error_type(err: &MarketplaceError) -> &'static str {
match err {
MarketplaceError::Io { .. } => "marketplace_io",
MarketplaceError::MarketplaceNotFound { .. } => "marketplace_not_found",
MarketplaceError::InvalidMarketplaceFile { .. } => "invalid_marketplace_file",
MarketplaceError::PluginNotFound { .. } => "plugin_not_found",
MarketplaceError::PluginNotAvailable { .. } => "plugin_not_available",
MarketplaceError::PluginsDisabled => "plugins_disabled",
MarketplaceError::InvalidPlugin(_) => "invalid_plugin",
}
}
pub(super) fn marketplace_error_sub_error_type(err: &MarketplaceError) -> Option<String> {
match err {
MarketplaceError::Io { context, .. } => Some(error_context_sub_error_type(context)),
MarketplaceError::MarketplaceNotFound { .. }
| MarketplaceError::InvalidMarketplaceFile { .. }
| MarketplaceError::PluginNotFound { .. }
| MarketplaceError::PluginNotAvailable { .. }
| MarketplaceError::PluginsDisabled
| MarketplaceError::InvalidPlugin(_) => None,
}
}
fn remote_plugin_mutation_error_type(err: &RemotePluginMutationError) -> &'static str {
match err {
RemotePluginMutationError::AuthRequired => "remote_mutation_auth_required",
RemotePluginMutationError::UnsupportedAuthMode => "remote_mutation_unsupported_auth_mode",
RemotePluginMutationError::AuthToken(_) => "remote_mutation_auth_token",
RemotePluginMutationError::InvalidBaseUrl(_) => "remote_mutation_invalid_base_url",
RemotePluginMutationError::InvalidBaseUrlPath => "remote_mutation_invalid_base_url_path",
RemotePluginMutationError::Request { .. } => "remote_mutation_request",
RemotePluginMutationError::UnexpectedStatus { .. } => "remote_mutation_unexpected_status",
RemotePluginMutationError::Decode { .. } => "remote_mutation_decode",
RemotePluginMutationError::UnexpectedPluginId { .. } => {
"remote_mutation_unexpected_plugin_id"
}
RemotePluginMutationError::UnexpectedEnabledState { .. } => {
"remote_mutation_unexpected_enabled_state"
}
}
}
fn plugin_store_error_type(err: &PluginStoreError) -> &'static str {
match err {
PluginStoreError::Io { .. } => "store_io",
PluginStoreError::Invalid(_) => "store_invalid",
}
}
#[derive(Debug, thiserror::Error)]
pub enum PluginUninstallError {
#[error("{0}")]
InvalidPluginId(#[from] PluginIdError),
#[error("{0}")]
Remote(#[from] RemotePluginMutationError),
#[error("{0}")]
Store(#[from] PluginStoreError),
#[error("{0}")]
Config(#[from] anyhow::Error),
#[error("failed to join plugin uninstall task: {0}")]
Join(#[from] tokio::task::JoinError),
}
impl PluginUninstallError {
pub(super) fn join(source: tokio::task::JoinError) -> Self {
Self::Join(source)
}
pub fn is_invalid_request(&self) -> bool {
matches!(self, Self::InvalidPluginId(_))
}
}