Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move aws_smithy_http::operation::error::BuildError into aws-smithy-types #3032

Merged
merged 10 commits into from
Oct 12, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProvider
import software.amazon.smithy.rust.codegen.core.smithy.generators.OperationBuildError
import software.amazon.smithy.rust.codegen.core.smithy.isOptional
import software.amazon.smithy.rust.codegen.core.util.inputShape

Expand Down Expand Up @@ -72,20 +71,18 @@ class EndpointTraitBindings(
rust("let $field = &$input.$field;")
}
if (generateValidation) {
val errorString = "$field was unset or empty but must be set as part of the endpoint prefix"
val contents =
// TODO(enableNewSmithyRuntimeCleanup): Remove the allow attribute once all places need .into method
"""
if $field.is_empty() {
##[allow(clippy::useless_conversion)]
return Err(#{invalidFieldError:W}.into())
return Err(#{InvalidEndpointError}::failed_to_construct_uri("$errorString").into());
}
"""
rustTemplate(
contents,
"invalidFieldError" to OperationBuildError(runtimeConfig).invalidField(
field,
"$field was unset or empty but must be set as part of the endpoint prefix",
),
"InvalidEndpointError" to RuntimeType.smithyHttp(runtimeConfig)
.resolve("endpoint::error::InvalidEndpointError"),
)
}
"${label.content} = $field"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ import software.amazon.smithy.rust.codegen.core.rustlang.CargoDependency
import software.amazon.smithy.rust.codegen.core.rustlang.RustModule
import software.amazon.smithy.rust.codegen.core.rustlang.implBlock
import software.amazon.smithy.rust.codegen.core.rustlang.rust
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.core.smithy.generators.operationBuildError
import software.amazon.smithy.rust.codegen.core.testutil.TestRuntimeConfig
import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace
import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel
Expand Down Expand Up @@ -70,10 +69,9 @@ internal class EndpointTraitBindingsTest {
""",
)
implBlock(symbolProvider.toSymbol(model.lookup("test#GetStatusInput"))) {
rustBlock(
"fn endpoint_prefix(&self) -> std::result::Result<#T::endpoint::EndpointPrefix, #T>",
RuntimeType.smithyHttp(TestRuntimeConfig),
TestRuntimeConfig.operationBuildError(),
rustBlockTemplate(
"fn endpoint_prefix(&self) -> std::result::Result<#{endpoint}::EndpointPrefix, #{endpoint}::error::InvalidEndpointError>",
"endpoint" to RuntimeType.smithyHttp(TestRuntimeConfig).resolve("endpoint"),
) {
endpointBindingGenerator.render(this, "self")
}
Expand Down
21 changes: 10 additions & 11 deletions rust-runtime/aws-smithy-http/src/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//! Code for resolving an endpoint (URI) that a request should be sent to

use crate::endpoint::error::InvalidEndpointError;
use crate::operation::error::BuildError;
use aws_smithy_types::config_bag::{Storable, StoreReplace};
use http::uri::{Authority, Uri};
use std::borrow::Cow;
Expand Down Expand Up @@ -105,15 +104,13 @@ impl<T> ResolveEndpoint<T> for Endpoint {
pub struct EndpointPrefix(String);
impl EndpointPrefix {
/// Create a new endpoint prefix from an `impl Into<String>`. If the prefix argument is invalid,
/// a [`BuildError`] will be returned.
pub fn new(prefix: impl Into<String>) -> StdResult<Self, BuildError> {
/// a [`InvalidEndpointError`] will be returned.
pub fn new(prefix: impl Into<String>) -> StdResult<Self, InvalidEndpointError> {
let prefix = prefix.into();
match Authority::from_str(&prefix) {
Ok(_) => Ok(EndpointPrefix(prefix)),
Err(err) => Err(BuildError::invalid_uri(
prefix,
"invalid prefix".into(),
err,
Err(err) => Err(InvalidEndpointError::failed_to_construct_authority(
prefix, err,
)),
}
}
Expand Down Expand Up @@ -143,11 +140,13 @@ pub fn apply_endpoint(
.map(|auth| auth.as_str())
.unwrap_or("");
let authority = if !prefix.is_empty() {
Authority::from_str(&format!("{}{}", prefix, authority))
Cow::Owned(format!("{}{}", prefix, authority))
} else {
Authority::from_str(authority)
}
.map_err(InvalidEndpointError::failed_to_construct_authority)?;
Cow::Borrowed(authority)
};
let authority = Authority::from_str(&authority).map_err(|err| {
InvalidEndpointError::failed_to_construct_authority(authority.into_owned(), err)
})?;
let scheme = *endpoint
.scheme()
.as_ref()
Expand Down
25 changes: 17 additions & 8 deletions rust-runtime/aws-smithy-http/src/endpoint/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ impl Error for ResolveEndpointError {
pub(super) enum InvalidEndpointErrorKind {
EndpointMustHaveScheme,
FailedToConstructAuthority {
authority: String,
source: Box<dyn Error + Send + Sync + 'static>,
},
FailedToConstructUri {
Expand All @@ -69,23 +70,28 @@ pub struct InvalidEndpointError {
}

impl InvalidEndpointError {
pub(super) fn endpoint_must_have_scheme() -> Self {
/// Construct a build error for a missing scheme
pub fn endpoint_must_have_scheme() -> Self {
Self {
kind: InvalidEndpointErrorKind::EndpointMustHaveScheme,
}
}

pub(super) fn failed_to_construct_authority(
/// Construct a build error for an invalid authority
pub fn failed_to_construct_authority(
authority: String,
ysaito1001 marked this conversation as resolved.
Show resolved Hide resolved
source: impl Into<Box<dyn Error + Send + Sync + 'static>>,
) -> Self {
Self {
kind: InvalidEndpointErrorKind::FailedToConstructAuthority {
authority,
source: source.into(),
},
}
}

pub(super) fn failed_to_construct_uri(
/// Construct a build error for an invalid URI
pub fn failed_to_construct_uri(
source: impl Into<Box<dyn Error + Send + Sync + 'static>>,
) -> Self {
Self {
Expand All @@ -105,11 +111,11 @@ impl From<InvalidEndpointErrorKind> for InvalidEndpointError {
impl fmt::Display for InvalidEndpointError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use InvalidEndpointErrorKind as ErrorKind;
match self.kind {
match &self.kind {
ErrorKind::EndpointMustHaveScheme => write!(f, "endpoint must contain a valid scheme"),
ErrorKind::FailedToConstructAuthority { .. } => write!(
ErrorKind::FailedToConstructAuthority { authority, source: _ } => write!(
f,
"endpoint must contain a valid authority when combined with endpoint prefix"
"endpoint must contain a valid authority when combined with endpoint prefix: {authority}"
),
ErrorKind::FailedToConstructUri { .. } => write!(f, "failed to construct URI"),
}
Expand All @@ -120,8 +126,11 @@ impl Error for InvalidEndpointError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
use InvalidEndpointErrorKind as ErrorKind;
match &self.kind {
ErrorKind::FailedToConstructUri { source }
| ErrorKind::FailedToConstructAuthority { source } => Some(source.as_ref()),
ErrorKind::FailedToConstructUri { source } => Some(source.as_ref()),
ErrorKind::FailedToConstructAuthority {
authority: _,
source,
} => Some(source.as_ref()),
ErrorKind::EndpointMustHaveScheme => None,
}
}
Expand Down
5 changes: 4 additions & 1 deletion rust-runtime/aws-smithy-http/src/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ use aws_smithy_types::config_bag::{Storable, StoreReplace};
use std::borrow::Cow;
use std::ops::{Deref, DerefMut};

pub mod error;
//TODO(runtimeCratesVersioningCleanup): Re-point those who use the following reexport to
// directly depend on `aws_smithy_types` and remove the reexport below.
/// Errors for operations
pub use aws_smithy_types::operation::error;

/// Metadata attached to an [`Operation`] that identifies the API being called.
#[derive(Clone, Debug)]
Expand Down
187 changes: 0 additions & 187 deletions rust-runtime/aws-smithy-http/src/operation/error.rs

This file was deleted.

1 change: 1 addition & 0 deletions rust-runtime/aws-smithy-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub mod config_bag;
pub mod date_time;
pub mod endpoint;
pub mod error;
pub mod operation;
pub mod primitive;
pub mod retry;
pub mod timeout;
Expand Down
Loading