blob: 0cf4067d140abed6834f6336b9791ea951100a6c [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
anyhow::Error,
clonable_error::ClonableError,
fidl_fuchsia_component as fcomponent, fuchsia_zircon as zx,
moniker::{AbsoluteMoniker, ExtendedMoniker, PartialMoniker, RelativeMoniker},
thiserror::Error,
};
/// Errors produced during routing.
#[derive(Debug, Error, Clone)]
pub enum RoutingError {
#[error("Instance identified as source of capability is not running: `{}`", moniker)]
SourceInstanceStopped { moniker: AbsoluteMoniker },
#[error(
"Instance identified as source of capability is a non-executable component: `{}`",
moniker
)]
SourceInstanceNotExecutable { moniker: AbsoluteMoniker },
#[error("Failed to open path `{}` in outgoing directory of `{}`: {}", path, moniker, err)]
OpenOutgoingFailed {
moniker: AbsoluteMoniker,
path: String,
#[source]
err: ClonableError,
},
#[error("Failed to open path `{}` in component manager's namespace: {}", path, err)]
OpenComponentManagerNamespaceFailed {
path: String,
#[source]
err: ClonableError,
},
#[error(
"Failed to open path `{}`, in storage directory for `{}` backed by `{}`: {}",
path,
relative_moniker,
moniker,
err
)]
OpenStorageFailed {
moniker: ExtendedMoniker,
relative_moniker: RelativeMoniker,
path: String,
#[source]
err: ClonableError,
},
#[error("Source for storage capability must be a component, but was `{}`", source_type)]
StorageSourceIsNotComponent { source_type: &'static str },
#[error(
"Source for directory backing storage from `{}` must be a component or component manager's namespace, but was {}",
storage_moniker,
source_type
)]
StorageDirectorySourceInvalid { source_type: &'static str, storage_moniker: AbsoluteMoniker },
#[error(
"Source for directory storage from `{}` was a child `{}`, but this child was not found",
storage_moniker,
child_moniker
)]
StorageDirectorySourceChildNotFound {
storage_moniker: AbsoluteMoniker,
child_moniker: PartialMoniker,
},
#[error(
"A `storage` declaration with a backing directory from child `{}` was found at `{}` for \
`{}`, but no matching `expose` declaration was found in the child",
child_moniker,
moniker,
capability_id
)]
StorageFromChildExposeNotFound {
child_moniker: PartialMoniker,
moniker: AbsoluteMoniker,
capability_id: String,
},
#[error(
"A `use from parent` declaration was found at `/` for `{}`, \
but no built-in capability matches",
capability_id
)]
UseFromComponentManagerNotFound { capability_id: String },
#[error(
"An `offer from parent` declaration was found at `/` for `{}`, \
but no built-in capability matches",
capability_id
)]
OfferFromComponentManagerNotFound { capability_id: String },
#[error(
"A `storage` declaration with a backing directory was found at `/` for `{}`, \
but no built-in capability matches",
capability_id
)]
StorageFromComponentManagerNotFound { capability_id: String },
#[error(
"A `use from parent` declaration was found at `{}` for `{}`, but no matching \
`offer` declaration was found in the parent",
moniker,
capability_id
)]
UseFromParentNotFound { moniker: AbsoluteMoniker, capability_id: String },
#[error(
"A `use` declaration was found at `{}` for {} `{}`, but no matching \
{} registration was found in the component's environment",
moniker,
capability_type,
capability_id,
capability_type
)]
UseFromEnvironmentNotFound {
moniker: AbsoluteMoniker,
capability_type: String,
capability_id: String,
},
#[error(
"An `environment` {} registration from `parent` was found at `{}` for `{}`, but no \
matching `offer` declaration was found in the parent",
capability_type,
moniker,
capability_id
)]
EnvironmentFromParentNotFound {
moniker: AbsoluteMoniker,
capability_type: String,
capability_id: String,
},
#[error(
"An `environment` {} registration from `#{}` was found at `{}` for `{}`, but no matching \
`expose` declaration was found in the child",
capability_type,
child_moniker,
moniker,
capability_id
)]
EnvironmentFromChildExposeNotFound {
child_moniker: PartialMoniker,
moniker: AbsoluteMoniker,
capability_type: String,
capability_id: String,
},
#[error(
"An `offer from parent` declaration was found at `{}` for `{}`, but no matching \
`offer` declaration was found in the parent",
moniker,
capability_id
)]
OfferFromParentNotFound { moniker: AbsoluteMoniker, capability_id: String },
#[error(
"A `storage` declaration with a backing directory from `parent` was found at `{}` for `{}`,
but no matching `offer` declaration was found in the parent",
moniker,
capability_id
)]
StorageFromParentNotFound { moniker: AbsoluteMoniker, capability_id: String },
#[error(
"An `offer from #{}` declaration was found at `{}` for `{}`, but no matching child was \
found",
child_moniker,
moniker,
capability_id
)]
OfferFromChildInstanceNotFound {
child_moniker: PartialMoniker,
moniker: AbsoluteMoniker,
capability_id: String,
},
#[error(
"An `offer from #{}` declaration was found at `{}` for `{}`, but no matching `expose` \
declaration was found in the child",
child_moniker,
moniker,
capability_id
)]
OfferFromChildExposeNotFound {
child_moniker: PartialMoniker,
moniker: AbsoluteMoniker,
capability_id: String,
},
// TODO: Could this be distinguished by use/offer/expose?
#[error(
"A framework capability was sourced to `{}` with id `{}`, but no such \
framework capability was found",
moniker,
capability_id
)]
CapabilityFromFrameworkNotFound { moniker: AbsoluteMoniker, capability_id: String },
#[error(
"A capability was sourced to a base capability `{}` from `{}`, but this is unsupported",
capability_id,
moniker
)]
CapabilityFromCapabilityNotFound { moniker: AbsoluteMoniker, capability_id: String },
// TODO: Could this be distinguished by use/offer/expose?
#[error(
"A capability was sourced to component manager with id `{}`, but no matching \
capability was found",
capability_id
)]
CapabilityFromComponentManagerNotFound { capability_id: String },
#[error(
"A capability was sourced to storage capability `{}` with id `{}`, but no matching \
capability was found",
storage_capability,
capability_id
)]
CapabilityFromStorageCapabilityNotFound { storage_capability: String, capability_id: String },
#[error(
"An exposed capability `{}` was used at `{}`, but no matching `expose` \
declaration was found",
capability_id,
moniker
)]
UsedExposeNotFound { moniker: AbsoluteMoniker, capability_id: String },
#[error(
"An `expose from #{}` declaration was found at `{}` for `{}`, but no matching child was \
found",
child_moniker,
moniker,
capability_id
)]
ExposeFromChildInstanceNotFound {
child_moniker: PartialMoniker,
moniker: AbsoluteMoniker,
capability_id: String,
},
#[error(
"An `expose from #{}` declaration was found at `{}` for `{}`, but no matching `expose` \
declaration was found in the child",
child_moniker,
moniker,
capability_id
)]
ExposeFromChildExposeNotFound {
child_moniker: PartialMoniker,
moniker: AbsoluteMoniker,
capability_id: String,
},
#[error(
"An `expose from framework` declaration was found at `{}` for `{}`, but no matching \
framework capability was found",
moniker,
capability_id
)]
ExposeFromFrameworkNotFound { moniker: AbsoluteMoniker, capability_id: String },
}
impl RoutingError {
/// Convert this error into its approximate `fuchsia.component.Error` equivalent.
pub fn as_fidl_error(&self) -> fcomponent::Error {
fcomponent::Error::ResourceUnavailable
}
/// Convert this error into its approximate `zx::Status` equivalent.
pub fn as_zx_status(&self) -> zx::Status {
zx::Status::UNAVAILABLE
}
pub fn source_instance_stopped(moniker: &AbsoluteMoniker) -> Self {
Self::SourceInstanceStopped { moniker: moniker.clone() }
}
pub fn source_instance_not_executable(moniker: &AbsoluteMoniker) -> Self {
Self::SourceInstanceNotExecutable { moniker: moniker.clone() }
}
pub fn open_outgoing_failed(
moniker: &AbsoluteMoniker,
path: impl Into<String>,
err: impl Into<Error>,
) -> Self {
Self::OpenOutgoingFailed {
moniker: moniker.clone(),
path: path.into(),
err: err.into().into(),
}
}
pub fn open_component_manager_namespace_failed(
path: impl Into<String>,
err: impl Into<Error>,
) -> Self {
Self::OpenComponentManagerNamespaceFailed { path: path.into(), err: err.into().into() }
}
pub fn open_storage_failed(
moniker: &ExtendedMoniker,
relative_moniker: &RelativeMoniker,
path: impl Into<String>,
err: impl Into<Error>,
) -> Self {
Self::OpenStorageFailed {
moniker: moniker.clone(),
relative_moniker: relative_moniker.clone(),
path: path.into(),
err: err.into().into(),
}
}
pub fn storage_source_is_not_component(source_type: &'static str) -> Self {
Self::StorageSourceIsNotComponent { source_type }
}
pub fn storage_directory_source_invalid(
source_type: &'static str,
storage_moniker: &AbsoluteMoniker,
) -> Self {
Self::StorageDirectorySourceInvalid {
source_type,
storage_moniker: storage_moniker.clone(),
}
}
pub fn storage_directory_source_child_not_found(
storage_moniker: &AbsoluteMoniker,
child_moniker: &PartialMoniker,
) -> Self {
Self::StorageDirectorySourceChildNotFound {
storage_moniker: storage_moniker.clone(),
child_moniker: child_moniker.clone(),
}
}
pub fn storage_from_child_expose_not_found(
child_moniker: &PartialMoniker,
moniker: &AbsoluteMoniker,
capability_id: impl Into<String>,
) -> Self {
Self::StorageFromChildExposeNotFound {
child_moniker: child_moniker.clone(),
moniker: moniker.clone(),
capability_id: capability_id.into(),
}
}
pub fn use_from_component_manager_not_found(capability_id: impl Into<String>) -> Self {
Self::UseFromComponentManagerNotFound { capability_id: capability_id.into() }
}
pub fn offer_from_component_manager_not_found(capability_id: impl Into<String>) -> Self {
Self::OfferFromComponentManagerNotFound { capability_id: capability_id.into() }
}
pub fn storage_from_component_manager_not_found(capability_id: impl Into<String>) -> Self {
Self::StorageFromComponentManagerNotFound { capability_id: capability_id.into() }
}
pub fn use_from_parent_not_found(
moniker: &AbsoluteMoniker,
capability_id: impl Into<String>,
) -> Self {
Self::UseFromParentNotFound {
moniker: moniker.clone(),
capability_id: capability_id.into(),
}
}
pub fn use_from_environment_not_found(
moniker: &AbsoluteMoniker,
capability_type: impl Into<String>,
capability_id: impl Into<String>,
) -> Self {
Self::UseFromEnvironmentNotFound {
moniker: moniker.clone(),
capability_type: capability_type.into(),
capability_id: capability_id.into(),
}
}
pub fn environment_from_parent_not_found(
moniker: &AbsoluteMoniker,
capability_type: impl Into<String>,
capability_id: impl Into<String>,
) -> Self {
Self::EnvironmentFromParentNotFound {
moniker: moniker.clone(),
capability_type: capability_type.into(),
capability_id: capability_id.into(),
}
}
pub fn environment_from_child_expose_not_found(
child_moniker: &PartialMoniker,
moniker: &AbsoluteMoniker,
capability_type: impl Into<String>,
capability_id: impl Into<String>,
) -> Self {
Self::EnvironmentFromChildExposeNotFound {
child_moniker: child_moniker.clone(),
moniker: moniker.clone(),
capability_type: capability_type.into(),
capability_id: capability_id.into(),
}
}
pub fn offer_from_parent_not_found(
moniker: &AbsoluteMoniker,
capability_id: impl Into<String>,
) -> Self {
Self::OfferFromParentNotFound {
moniker: moniker.clone(),
capability_id: capability_id.into(),
}
}
pub fn storage_from_parent_not_found(
moniker: &AbsoluteMoniker,
capability_id: impl Into<String>,
) -> Self {
Self::StorageFromParentNotFound {
moniker: moniker.clone(),
capability_id: capability_id.into(),
}
}
pub fn offer_from_child_instance_not_found(
child_moniker: &PartialMoniker,
moniker: &AbsoluteMoniker,
capability_id: impl Into<String>,
) -> Self {
Self::OfferFromChildInstanceNotFound {
child_moniker: child_moniker.clone(),
moniker: moniker.clone(),
capability_id: capability_id.into(),
}
}
pub fn offer_from_child_expose_not_found(
child_moniker: &PartialMoniker,
moniker: &AbsoluteMoniker,
capability_id: impl Into<String>,
) -> Self {
Self::OfferFromChildExposeNotFound {
child_moniker: child_moniker.clone(),
moniker: moniker.clone(),
capability_id: capability_id.into(),
}
}
pub fn used_expose_not_found(
moniker: &AbsoluteMoniker,
capability_id: impl Into<String>,
) -> Self {
Self::UsedExposeNotFound { moniker: moniker.clone(), capability_id: capability_id.into() }
}
pub fn expose_from_child_instance_not_found(
child_moniker: &PartialMoniker,
moniker: &AbsoluteMoniker,
capability_id: impl Into<String>,
) -> Self {
Self::ExposeFromChildInstanceNotFound {
child_moniker: child_moniker.clone(),
moniker: moniker.clone(),
capability_id: capability_id.into(),
}
}
pub fn expose_from_child_expose_not_found(
child_moniker: &PartialMoniker,
moniker: &AbsoluteMoniker,
capability_id: impl Into<String>,
) -> Self {
Self::ExposeFromChildExposeNotFound {
child_moniker: child_moniker.clone(),
moniker: moniker.clone(),
capability_id: capability_id.into(),
}
}
pub fn capability_from_framework_not_found(
moniker: &AbsoluteMoniker,
capability_id: impl Into<String>,
) -> Self {
Self::CapabilityFromFrameworkNotFound {
moniker: moniker.clone(),
capability_id: capability_id.into(),
}
}
pub fn capability_from_capability_not_found(
moniker: &AbsoluteMoniker,
capability_id: impl Into<String>,
) -> Self {
Self::CapabilityFromCapabilityNotFound {
moniker: moniker.clone(),
capability_id: capability_id.into(),
}
}
pub fn capability_from_component_manager_not_found(capability_id: impl Into<String>) -> Self {
Self::CapabilityFromComponentManagerNotFound { capability_id: capability_id.into() }
}
pub fn capability_from_storage_capability_not_found(
storage_capability: impl Into<String>,
capability_id: impl Into<String>,
) -> Self {
Self::CapabilityFromStorageCapabilityNotFound {
storage_capability: storage_capability.into(),
capability_id: capability_id.into(),
}
}
pub fn expose_from_framework_not_found(
moniker: &AbsoluteMoniker,
capability_id: impl Into<String>,
) -> Self {
Self::ExposeFromFrameworkNotFound {
moniker: moniker.clone(),
capability_id: capability_id.into(),
}
}
}