Loading codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/error/CombinedErrorGenerator.kt +8 −9 Original line number Diff line number Diff line Loading @@ -166,9 +166,9 @@ class CombinedErrorGenerator( rust( """ /// An unexpected error, e.g. invalid JSON returned by the service or an unknown error code Unhandled(Box<dyn #T + Send + Sync + 'static>), Unhandled(#T), """, RuntimeType.StdError, unhandledError(), ) } writer.rustBlock("impl #T for ${errorSymbol.name}", RuntimeType.Display) { Loading Loading @@ -215,7 +215,7 @@ class CombinedErrorGenerator( /// Creates the `${errorSymbol.name}::Unhandled` variant from any error type. pub fn unhandled(err: impl Into<Box<dyn #{std_error} + Send + Sync + 'static>>) -> Self { Self { kind: ${errorSymbol.name}Kind::Unhandled(err.into()), kind: ${errorSymbol.name}Kind::Unhandled(#{Unhandled}::new(err.into())), meta: Default::default() } } Loading @@ -224,7 +224,7 @@ class CombinedErrorGenerator( pub fn generic(err: #{generic_error}) -> Self { Self { meta: err.clone(), kind: ${errorSymbol.name}Kind::Unhandled(err.into()), kind: ${errorSymbol.name}Kind::Unhandled(#{Unhandled}::new(err.into())), } } Loading @@ -249,7 +249,9 @@ class CombinedErrorGenerator( self.meta.code() } """, "generic_error" to genericError, "std_error" to RuntimeType.StdError, "generic_error" to genericError, "std_error" to RuntimeType.StdError, "Unhandled" to unhandledError(), ) errors.forEach { error -> val errorVariantSymbol = symbolProvider.toSymbol(error) Loading @@ -265,10 +267,7 @@ class CombinedErrorGenerator( rustBlock("fn source(&self) -> Option<&(dyn #T + 'static)>", RuntimeType.StdError) { delegateToVariants(errors, errorSymbol) { writable { when (it) { is VariantMatch.Unhandled -> rust("Some(_inner.as_ref())") is VariantMatch.Modeled -> rust("Some(_inner)") } rust("Some(_inner)") } } } Loading codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/error/TopLevelErrorGenerator.kt +12 −7 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import software.amazon.smithy.rust.codegen.core.rustlang.documentShape 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.CodegenContext import software.amazon.smithy.rust.codegen.core.smithy.CodegenTarget import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType Loading Loading @@ -92,17 +93,17 @@ class TopLevelErrorGenerator(private val codegenContext: CodegenContext, private } } private fun RustWriter.renderImplFrom(symbol: RuntimeType, errors: List<ShapeId>) { private fun RustWriter.renderImplFrom(errorSymbol: RuntimeType, errors: List<ShapeId>) { if (errors.isNotEmpty() || CodegenTarget.CLIENT == codegenContext.target) { rustBlock( "impl<R> From<#T<#T, R>> for Error where R: Send + Sync + std::fmt::Debug + 'static", sdkError, symbol, errorSymbol, ) { rustBlockTemplate( "fn from(err: #{SdkError}<#{OpError}, R>) -> Self", "SdkError" to sdkError, "OpError" to symbol, "OpError" to errorSymbol, ) { rustBlock("match err") { val operationErrors = errors.map { model.expectShape(it) } Loading @@ -111,12 +112,16 @@ class TopLevelErrorGenerator(private val codegenContext: CodegenContext, private val errSymbol = symbolProvider.toSymbol(errorShape) rust( "#TKind::${errSymbol.name}(inner) => Error::${errSymbol.name}(inner),", symbol, errorSymbol, ) } rust("#TKind::Unhandled(inner) => Error::Unhandled(inner),", symbol) rustTemplate( "#{errorSymbol}Kind::Unhandled(inner) => Error::Unhandled(#{unhandled}::new(inner.into())),", "errorSymbol" to errorSymbol, "unhandled" to unhandledError(), ) } rust("_ => Error::Unhandled(err.into()),") rust("_ => Error::Unhandled(#T::new(err.into())),", unhandledError()) } } } Loading @@ -137,7 +142,7 @@ class TopLevelErrorGenerator(private val codegenContext: CodegenContext, private rust("${sym.name}(#T),", sym) } rust("/// An unhandled error occurred.") rust("Unhandled(Box<dyn #T + Send + Sync + 'static>)", RuntimeType.StdError) rust("Unhandled(#T)", unhandledError()) } } } codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/error/UnhandledErrorGenerator.kt 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ package software.amazon.smithy.rust.codegen.core.smithy.generators.error import software.amazon.smithy.rust.codegen.core.rustlang.RustModule import software.amazon.smithy.rust.codegen.core.rustlang.docs 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.smithy.RuntimeType internal fun unhandledError(): RuntimeType = RuntimeType.forInlineFun("Unhandled", RustModule.Error) { docs( """ An unexpected error occurred (e.g., invalid JSON returned by the service or an unknown error code) Call [`Error::source`](std::error::Error::source) for more details about the underlying cause. """, ) rust("##[derive(Debug)]") rustBlock("pub struct Unhandled") { rust("source: Box<dyn #T + Send + Sync + 'static>", RuntimeType.StdError) } rustBlock("impl Unhandled") { rustBlock("pub(crate) fn new(source: Box<dyn #T + Send + Sync + 'static>) -> Self", RuntimeType.StdError) { rust("Self { source }") } } rustBlock("impl std::fmt::Display for Unhandled") { rustBlock("fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error>") { rust("write!(f, \"unhandled error\")") } } rustBlock("impl std::error::Error for Unhandled") { rustBlock("fn source(&self) -> Option<&(dyn std::error::Error + 'static)>") { rust("Some(self.source.as_ref() as _)") } } } codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/protocols/parse/EventStreamUnmarshallerGeneratorTest.kt +3 −1 Original line number Diff line number Diff line Loading @@ -275,7 +275,9 @@ class EventStreamUnmarshallerGeneratorTest { assert!(result.is_ok(), "expected ok, got: {:?}", result); match expect_error(result.unwrap())$kindSuffix { TestStreamErrorKind::Unhandled(err) => { assert!(format!("{}", err).contains("message: \"unmodeled error\"")); let message = format!("{}", aws_smithy_types::error::display::DisplayErrorContext(&err)); let expected = "message: \"unmodeled error\""; assert!(message.contains(expected), "Expected '{message}' to contain '{expected}'"); } kind => panic!("expected generic error, but got {:?}", kind), } Loading Loading
codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/error/CombinedErrorGenerator.kt +8 −9 Original line number Diff line number Diff line Loading @@ -166,9 +166,9 @@ class CombinedErrorGenerator( rust( """ /// An unexpected error, e.g. invalid JSON returned by the service or an unknown error code Unhandled(Box<dyn #T + Send + Sync + 'static>), Unhandled(#T), """, RuntimeType.StdError, unhandledError(), ) } writer.rustBlock("impl #T for ${errorSymbol.name}", RuntimeType.Display) { Loading Loading @@ -215,7 +215,7 @@ class CombinedErrorGenerator( /// Creates the `${errorSymbol.name}::Unhandled` variant from any error type. pub fn unhandled(err: impl Into<Box<dyn #{std_error} + Send + Sync + 'static>>) -> Self { Self { kind: ${errorSymbol.name}Kind::Unhandled(err.into()), kind: ${errorSymbol.name}Kind::Unhandled(#{Unhandled}::new(err.into())), meta: Default::default() } } Loading @@ -224,7 +224,7 @@ class CombinedErrorGenerator( pub fn generic(err: #{generic_error}) -> Self { Self { meta: err.clone(), kind: ${errorSymbol.name}Kind::Unhandled(err.into()), kind: ${errorSymbol.name}Kind::Unhandled(#{Unhandled}::new(err.into())), } } Loading @@ -249,7 +249,9 @@ class CombinedErrorGenerator( self.meta.code() } """, "generic_error" to genericError, "std_error" to RuntimeType.StdError, "generic_error" to genericError, "std_error" to RuntimeType.StdError, "Unhandled" to unhandledError(), ) errors.forEach { error -> val errorVariantSymbol = symbolProvider.toSymbol(error) Loading @@ -265,10 +267,7 @@ class CombinedErrorGenerator( rustBlock("fn source(&self) -> Option<&(dyn #T + 'static)>", RuntimeType.StdError) { delegateToVariants(errors, errorSymbol) { writable { when (it) { is VariantMatch.Unhandled -> rust("Some(_inner.as_ref())") is VariantMatch.Modeled -> rust("Some(_inner)") } rust("Some(_inner)") } } } Loading
codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/error/TopLevelErrorGenerator.kt +12 −7 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import software.amazon.smithy.rust.codegen.core.rustlang.documentShape 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.CodegenContext import software.amazon.smithy.rust.codegen.core.smithy.CodegenTarget import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType Loading Loading @@ -92,17 +93,17 @@ class TopLevelErrorGenerator(private val codegenContext: CodegenContext, private } } private fun RustWriter.renderImplFrom(symbol: RuntimeType, errors: List<ShapeId>) { private fun RustWriter.renderImplFrom(errorSymbol: RuntimeType, errors: List<ShapeId>) { if (errors.isNotEmpty() || CodegenTarget.CLIENT == codegenContext.target) { rustBlock( "impl<R> From<#T<#T, R>> for Error where R: Send + Sync + std::fmt::Debug + 'static", sdkError, symbol, errorSymbol, ) { rustBlockTemplate( "fn from(err: #{SdkError}<#{OpError}, R>) -> Self", "SdkError" to sdkError, "OpError" to symbol, "OpError" to errorSymbol, ) { rustBlock("match err") { val operationErrors = errors.map { model.expectShape(it) } Loading @@ -111,12 +112,16 @@ class TopLevelErrorGenerator(private val codegenContext: CodegenContext, private val errSymbol = symbolProvider.toSymbol(errorShape) rust( "#TKind::${errSymbol.name}(inner) => Error::${errSymbol.name}(inner),", symbol, errorSymbol, ) } rust("#TKind::Unhandled(inner) => Error::Unhandled(inner),", symbol) rustTemplate( "#{errorSymbol}Kind::Unhandled(inner) => Error::Unhandled(#{unhandled}::new(inner.into())),", "errorSymbol" to errorSymbol, "unhandled" to unhandledError(), ) } rust("_ => Error::Unhandled(err.into()),") rust("_ => Error::Unhandled(#T::new(err.into())),", unhandledError()) } } } Loading @@ -137,7 +142,7 @@ class TopLevelErrorGenerator(private val codegenContext: CodegenContext, private rust("${sym.name}(#T),", sym) } rust("/// An unhandled error occurred.") rust("Unhandled(Box<dyn #T + Send + Sync + 'static>)", RuntimeType.StdError) rust("Unhandled(#T)", unhandledError()) } } }
codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/error/UnhandledErrorGenerator.kt 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ package software.amazon.smithy.rust.codegen.core.smithy.generators.error import software.amazon.smithy.rust.codegen.core.rustlang.RustModule import software.amazon.smithy.rust.codegen.core.rustlang.docs 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.smithy.RuntimeType internal fun unhandledError(): RuntimeType = RuntimeType.forInlineFun("Unhandled", RustModule.Error) { docs( """ An unexpected error occurred (e.g., invalid JSON returned by the service or an unknown error code) Call [`Error::source`](std::error::Error::source) for more details about the underlying cause. """, ) rust("##[derive(Debug)]") rustBlock("pub struct Unhandled") { rust("source: Box<dyn #T + Send + Sync + 'static>", RuntimeType.StdError) } rustBlock("impl Unhandled") { rustBlock("pub(crate) fn new(source: Box<dyn #T + Send + Sync + 'static>) -> Self", RuntimeType.StdError) { rust("Self { source }") } } rustBlock("impl std::fmt::Display for Unhandled") { rustBlock("fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error>") { rust("write!(f, \"unhandled error\")") } } rustBlock("impl std::error::Error for Unhandled") { rustBlock("fn source(&self) -> Option<&(dyn std::error::Error + 'static)>") { rust("Some(self.source.as_ref() as _)") } } }
codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/protocols/parse/EventStreamUnmarshallerGeneratorTest.kt +3 −1 Original line number Diff line number Diff line Loading @@ -275,7 +275,9 @@ class EventStreamUnmarshallerGeneratorTest { assert!(result.is_ok(), "expected ok, got: {:?}", result); match expect_error(result.unwrap())$kindSuffix { TestStreamErrorKind::Unhandled(err) => { assert!(format!("{}", err).contains("message: \"unmodeled error\"")); let message = format!("{}", aws_smithy_types::error::display::DisplayErrorContext(&err)); let expected = "message: \"unmodeled error\""; assert!(message.contains(expected), "Expected '{message}' to contain '{expected}'"); } kind => panic!("expected generic error, but got {:?}", kind), } Loading