diff --git a/src/viam/sdk/CMakeLists.txt b/src/viam/sdk/CMakeLists.txt index 2e335f51a..88330c663 100644 --- a/src/viam/sdk/CMakeLists.txt +++ b/src/viam/sdk/CMakeLists.txt @@ -46,6 +46,7 @@ target_sources(viamsdk common/linear_algebra.cpp common/pose.cpp common/proto_type.cpp + common/service_helper.cpp common/utils.cpp common/world_state.cpp components/base/base.cpp diff --git a/src/viam/sdk/common/service_helper.cpp b/src/viam/sdk/common/service_helper.cpp new file mode 100644 index 000000000..317dff535 --- /dev/null +++ b/src/viam/sdk/common/service_helper.cpp @@ -0,0 +1,42 @@ +#include + +#include + +namespace viam { +namespace sdk { + +::grpc::Status ServiceHelperBase::fail(::grpc::StatusCode code, const char* message) const noexcept + try { + std::ostringstream stream; + stream << '[' << method_ << "]: " << message; + return {code, stream.str()}; +} catch (...) { + return {code, message}; +} + +::grpc::Status ServiceHelperBase::failNoRequest() const noexcept { + return fail(::grpc::INVALID_ARGUMENT, "Called without a `request` object"); +} + +::grpc::Status ServiceHelperBase::failNoResource(const std::string& name) const noexcept try { + std::ostringstream stream; + stream << "Failed to find resource `" << name << "`"; + return fail(::grpc::NOT_FOUND, stream.str().c_str()); +} catch (...) { + return fail(::grpc::NOT_FOUND, "Failed to find resource"); +} + +::grpc::Status ServiceHelperBase::failStdException(const std::exception& xcp) const noexcept try { + std::ostringstream stream; + stream << "Failed with a std::exception: " << xcp.what(); + return fail(::grpc::INTERNAL, stream.str().c_str()); +} catch (...) { + return fail(::grpc::INTERNAL, "Failed with a std::exception: "); +} + +::grpc::Status ServiceHelperBase::failUnknownException() const noexcept { + return fail(::grpc::INTERNAL, "Failed with an unknown exception"); +} + +} // namespace sdk +} // namespace viam diff --git a/src/viam/sdk/common/service_helper.hpp b/src/viam/sdk/common/service_helper.hpp new file mode 100644 index 000000000..0a21d6cd0 --- /dev/null +++ b/src/viam/sdk/common/service_helper.hpp @@ -0,0 +1,92 @@ +#pragma once + +#include + +#include + +namespace viam { +namespace sdk { + +class ServiceHelperBase { + public: + ::grpc::Status fail(::grpc::StatusCode code, const char* message) const noexcept; + + ::grpc::Status failNoRequest() const noexcept; + + ::grpc::Status failNoResource(const std::string& name) const noexcept; + + ::grpc::Status failStdException(const std::exception& xcp) const noexcept; + + ::grpc::Status failUnknownException() const noexcept; + + protected: + explicit ServiceHelperBase(const char* method) noexcept : method_{method} {} + + private: + const char* method_; +}; + +template +class ServiceHelper : public ServiceHelperBase { + public: + ServiceHelper(const char* method, ResourceServer* rs, RequestType* request) noexcept + : ServiceHelperBase{method}, rs_{rs}, request_{request} {}; + + template + ::grpc::Status operator()(Callable&& callable) const noexcept try { + if (!request_) { + return failNoRequest(); + } + const auto resource = rs_->resource_manager()->resource(request_->name()); + if (!resource) { + return failNoResource(request_->name()); + } + return invoke_(std::forward(callable), std::move(resource)); + } catch (const std::exception& xcp) { + return failStdException(xcp); + } catch (...) { + return failUnknownException(); + } + + auto getExtra() const { + return request_->has_extra() ? struct_to_map(request_->extra()) : AttributeMap{}; + } + + private: + template + using is_void_result = std::is_void>; + + // Implementation of `invoke_` for a Callable returning non-void, + // presumably an error return, which we return as a + // ::grpc::Status. + template ::value, + bool> = true> + ::grpc::Status invoke_(Callable&& callable, ResourcePtrType&& resource) const { + return std::forward(callable)(*this, std::forward(resource)); + } + + // Implementation of `invoke_` for a Callable returning void, + // which is therefore either non-failing or communicates errors by + // throwing exceptions. We return an OK status automatically. + template ::value, + bool> = true> + ::grpc::Status invoke_(Callable&& callable, ResourcePtrType&& resource) const { + std::forward(callable)(*this, std::forward(resource)); + return {}; + } + + ResourceServer* rs_; + RequestType* request_; +}; + +template +auto make_service_helper(const char* method, ResourceServer* rs, RequestType* request) { + return ServiceHelper{method, rs, request}; +} + +} // namespace sdk +} // namespace viam diff --git a/src/viam/sdk/components/encoder/server.cpp b/src/viam/sdk/components/encoder/server.cpp index 586c076fa..521e64183 100644 --- a/src/viam/sdk/components/encoder/server.cpp +++ b/src/viam/sdk/components/encoder/server.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -14,132 +15,57 @@ EncoderServer::EncoderServer(std::shared_ptr manager) : Resourc ::grpc::Status EncoderServer::GetPosition( ::grpc::ServerContext* context, const ::viam::component::encoder::v1::GetPositionRequest* request, - ::viam::component::encoder::v1::GetPositionResponse* response) { - if (!request) { - return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, - "Called [Encoder::GetPosition] without a request"); - }; - - const std::shared_ptr rb = resource_manager()->resource(request->name()); - if (!rb) { - return grpc::Status(grpc::UNKNOWN, "resource not found: " + request->name()); - } - - const std::shared_ptr encoder = std::dynamic_pointer_cast(rb); - - AttributeMap extra; - if (request->has_extra()) { - extra = struct_to_map(request->extra()); - } - - const Encoder::position result = - encoder->get_position(extra, Encoder::from_proto(request->position_type())); - response->set_value(result.value); - response->set_position_type(Encoder::to_proto(result.type)); - - return ::grpc::Status(); + ::viam::component::encoder::v1::GetPositionResponse* response) noexcept { + return make_service_helper( + "EncoderServer::GetPosition", this, request)([&](auto& helper, auto& encoder) { + const Encoder::position result = + encoder->get_position(helper.getExtra(), Encoder::from_proto(request->position_type())); + response->set_value(result.value); + response->set_position_type(Encoder::to_proto(result.type)); + }); } ::grpc::Status EncoderServer::ResetPosition( ::grpc::ServerContext* context, const ::viam::component::encoder::v1::ResetPositionRequest* request, - ::viam::component::encoder::v1::ResetPositionResponse* response) { - if (!request) { - return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, - "Called [Encoder::ResetPosition] without a request"); - }; - - const std::shared_ptr rb = resource_manager()->resource(request->name()); - if (!rb) { - return grpc::Status(grpc::UNKNOWN, "resource not found: " + request->name()); - } - - const std::shared_ptr encoder = std::dynamic_pointer_cast(rb); - - AttributeMap extra; - if (request->has_extra()) { - extra = struct_to_map(request->extra()); - } - - encoder->reset_position(extra); - - return ::grpc::Status(); + ::viam::component::encoder::v1::ResetPositionResponse* response) noexcept { + return make_service_helper("EncoderServer::ResetPosition", this, request)( + [&](auto& helper, auto& encoder) { encoder->reset_position(helper.getExtra()); }); } ::grpc::Status EncoderServer::GetProperties( ::grpc::ServerContext* context, const ::viam::component::encoder::v1::GetPropertiesRequest* request, - ::viam::component::encoder::v1::GetPropertiesResponse* response) { - if (!request) { - return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, - "Called [Encoder::GetProperties] without a request"); - }; - - const std::shared_ptr rb = resource_manager()->resource(request->name()); - if (!rb) { - return grpc::Status(grpc::UNKNOWN, "resource not found: " + request->name()); - } - - const std::shared_ptr encoder = std::dynamic_pointer_cast(rb); - - AttributeMap extra; - if (request->has_extra()) { - extra = struct_to_map(request->extra()); - } - - const Encoder::properties result = encoder->get_properties(extra); - response->set_ticks_count_supported(result.ticks_count_supported); - response->set_angle_degrees_supported(result.angle_degrees_supported); - - return ::grpc::Status(); + ::viam::component::encoder::v1::GetPropertiesResponse* response) noexcept { + return make_service_helper( + "EncoderServer::GetProperties", this, request)([&](auto& helper, auto& encoder) { + const Encoder::properties result = encoder->get_properties(helper.getExtra()); + response->set_ticks_count_supported(result.ticks_count_supported); + response->set_angle_degrees_supported(result.angle_degrees_supported); + }); } -::grpc::Status EncoderServer::GetGeometries(::grpc::ServerContext* context, - const ::viam::common::v1::GetGeometriesRequest* request, - ::viam::common::v1::GetGeometriesResponse* response) { - if (!request) { - return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, - "Called [GetGeometries] without a request"); - }; - - const std::shared_ptr rb = resource_manager()->resource(request->name()); - if (!rb) { - return grpc::Status(grpc::UNKNOWN, "resource not found: " + request->name()); - } - - AttributeMap extra; - if (request->has_extra()) { - extra = struct_to_map(request->extra()); - } - - const std::shared_ptr encoder = std::dynamic_pointer_cast(rb); - const std::vector geometries = encoder->get_geometries(extra); - for (const auto& geometry : geometries) { - *response->mutable_geometries()->Add() = geometry.to_proto(); - } - - return ::grpc::Status(); +::grpc::Status EncoderServer::GetGeometries( + ::grpc::ServerContext* context, + const ::viam::common::v1::GetGeometriesRequest* request, + ::viam::common::v1::GetGeometriesResponse* response) noexcept { + return make_service_helper( + "EncoderServer::GetGeometries", this, request)([&](auto& helper, auto& encoder) { + const std::vector geometries = encoder->get_geometries(helper.getExtra()); + for (const auto& geometry : geometries) { + *response->mutable_geometries()->Add() = geometry.to_proto(); + } + }); } ::grpc::Status EncoderServer::DoCommand(grpc::ServerContext* context, const viam::common::v1::DoCommandRequest* request, - viam::common::v1::DoCommandResponse* response) { - if (!request) { - return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, - "Called [Encoder::DoCommand] without a request"); - }; - - const std::shared_ptr rb = resource_manager()->resource(request->name()); - if (!rb) { - return grpc::Status(grpc::UNKNOWN, "resource not found: " + request->name()); - } - - const std::shared_ptr encoder = std::dynamic_pointer_cast(rb); - const AttributeMap result = encoder->do_command(struct_to_map(request->command())); - - *response->mutable_result() = map_to_struct(result); - - return ::grpc::Status(); + viam::common::v1::DoCommandResponse* response) noexcept { + return make_service_helper( + "EncoderServer::DoCommand", this, request)([&](auto& helper, auto& encoder) { + const AttributeMap result = encoder->do_command(struct_to_map(request->command())); + *response->mutable_result() = map_to_struct(result); + }); } void EncoderServer::register_server(std::shared_ptr server) { diff --git a/src/viam/sdk/components/encoder/server.hpp b/src/viam/sdk/components/encoder/server.hpp index d5c7745df..f20417344 100644 --- a/src/viam/sdk/components/encoder/server.hpp +++ b/src/viam/sdk/components/encoder/server.hpp @@ -24,25 +24,26 @@ class EncoderServer : public ResourceServer, ::grpc::Status GetPosition( ::grpc::ServerContext* context, const ::viam::component::encoder::v1::GetPositionRequest* request, - ::viam::component::encoder::v1::GetPositionResponse* response) override; + ::viam::component::encoder::v1::GetPositionResponse* response) noexcept override; ::grpc::Status ResetPosition( ::grpc::ServerContext* context, const ::viam::component::encoder::v1::ResetPositionRequest* request, - ::viam::component::encoder::v1::ResetPositionResponse* response) override; + ::viam::component::encoder::v1::ResetPositionResponse* response) noexcept override; ::grpc::Status GetProperties( ::grpc::ServerContext* context, const ::viam::component::encoder::v1::GetPropertiesRequest* request, - ::viam::component::encoder::v1::GetPropertiesResponse* response) override; + ::viam::component::encoder::v1::GetPropertiesResponse* response) noexcept override; - ::grpc::Status GetGeometries(::grpc::ServerContext* context, - const ::viam::common::v1::GetGeometriesRequest* request, - ::viam::common::v1::GetGeometriesResponse* response) override; + ::grpc::Status GetGeometries( + ::grpc::ServerContext* context, + const ::viam::common::v1::GetGeometriesRequest* request, + ::viam::common::v1::GetGeometriesResponse* response) noexcept override; ::grpc::Status DoCommand(grpc::ServerContext* context, const viam::common::v1::DoCommandRequest* request, - viam::common::v1::DoCommandResponse* response) override; + viam::common::v1::DoCommandResponse* response) noexcept override; void register_server(std::shared_ptr server) override; }; diff --git a/src/viam/sdk/resource/resource_manager.hpp b/src/viam/sdk/resource/resource_manager.hpp index 26929b5e0..c48a2f1b6 100644 --- a/src/viam/sdk/resource/resource_manager.hpp +++ b/src/viam/sdk/resource/resource_manager.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -27,6 +28,15 @@ class ResourceManager { /// @throws `std::runtime_error` if the desired resource does not exist. std::shared_ptr resource(const std::string& name); + /// @brief Returns a resource after dynamically downcasting to `T`. + /// @param name of the desired resource. + /// @throws `std::runtime_error` if the desired resource does not exist. + template + std::shared_ptr resource(const std::string& name) { + static_assert(std::is_base_of::value, "T is not derived from Resource"); + return std::dynamic_pointer_cast(resource(name)); + } + /// @brief Replaces all resources in the manager. /// @param resources The resources to replace with. void replace_all(const std::unordered_map>& resources); diff --git a/src/viam/sdk/services/mlmodel/server.cpp b/src/viam/sdk/services/mlmodel/server.cpp index f98ac3bd7..dfb03c58f 100644 --- a/src/viam/sdk/services/mlmodel/server.cpp +++ b/src/viam/sdk/services/mlmodel/server.cpp @@ -14,6 +14,7 @@ #include +#include #include #include #include @@ -34,184 +35,134 @@ void MLModelServiceServer::register_server(std::shared_ptr server) { ::grpc::Status MLModelServiceServer::Infer( ::grpc::ServerContext* context, const ::viam::service::mlmodel::v1::InferRequest* request, - ::viam::service::mlmodel::v1::InferResponse* response) noexcept try { - if (!request) { - return {::grpc::StatusCode::INVALID_ARGUMENT, "Called [Infer] without a request"}; - }; - - std::shared_ptr rb = resource_manager()->resource(request->name()); - - if (!rb) { - return {::grpc::UNKNOWN, "resource not found: " + request->name()}; - } - - std::shared_ptr mlms = std::dynamic_pointer_cast(rb); - - if (!request->has_input_tensors()) { - return {::grpc::StatusCode::INVALID_ARGUMENT, "Called [Infer] with no inputs"}; - } - - AttributeMap extra; - if (request->has_extra()) { - extra = struct_to_map(request->extra()); - } - - const auto md = mlms->metadata(extra); - MLModelService::named_tensor_views inputs; - for (const auto& input : md.inputs) { - const auto where = request->input_tensors().tensors().find(input.name); - if (where == request->input_tensors().tensors().end()) { - // Ignore any inputs for which we don't have metadata, since - // we can't validate the type info. - // - // TODO: Should this be an error? For now we just don't decode - // those tensors. - continue; + ::viam::service::mlmodel::v1::InferResponse* response) noexcept { + return make_service_helper( + "MLModelServiceServer::Infer", this, request)([&](auto& helper, auto& mlms) { + if (!request->has_input_tensors()) { + return helper.fail(::grpc::INVALID_ARGUMENT, "Called with no input tensors"); } - auto tensor = mlmodel_details::make_sdk_tensor_from_api_tensor(where->second); - const auto tensor_type = MLModelService::tensor_info::tensor_views_to_data_type(tensor); - if (tensor_type != input.data_type) { - std::ostringstream message; - using ut = std::underlying_type::type; - message << "Tensor input `" << input.name << "` was the wrong type; expected type " - << static_cast(input.data_type) << " but got type " - << static_cast(tensor_type); - return ::grpc::Status(grpc::INVALID_ARGUMENT, message.str()); + + const auto md = mlms->metadata({}); + MLModelService::named_tensor_views inputs; + for (const auto& input : md.inputs) { + const auto where = request->input_tensors().tensors().find(input.name); + if (where == request->input_tensors().tensors().end()) { + // Ignore any inputs for which we don't have metadata, since + // we can't validate the type info. + // + // TODO: Should this be an error? For now we just don't decode + // those tensors. + continue; + } + auto tensor = mlmodel_details::make_sdk_tensor_from_api_tensor(where->second); + const auto tensor_type = MLModelService::tensor_info::tensor_views_to_data_type(tensor); + if (tensor_type != input.data_type) { + std::ostringstream message; + using ut = std::underlying_type::type; + message << "Tensor input `" << input.name << "` was the wrong type; expected type " + << static_cast(input.data_type) << " but got type " + << static_cast(tensor_type); + return helper.fail(::grpc::INVALID_ARGUMENT, message.str().c_str()); + } + inputs.emplace(std::move(input.name), std::move(tensor)); } - inputs.emplace(std::move(input.name), std::move(tensor)); - } - - const auto outputs = mlms->infer(inputs, extra); - - auto* const output_tensors = response->mutable_output_tensors()->mutable_tensors(); - for (const auto& kv : *outputs) { - auto& emplaced = (*output_tensors)[kv.first]; - mlmodel_details::copy_sdk_tensor_to_api_tensor(kv.second, &emplaced); - } - return ::grpc::Status(); -} catch (...) { - // TODO(RSDK-3556): This is pretty bad. Investigate ways to - // simplify this, or decide against having clang-tidy enforce - // noexcept, or decide that letting gRPC deal with thrown - // exceptions is OK. - try { - try { - throw; - } catch (const std::exception& ex) { - return ::grpc::Status(grpc::INTERNAL, - std::string("[Infer]: Failed with exception: ") + ex.what()); - } catch (...) { - return ::grpc::Status(grpc::INTERNAL, "[Infer]: Failed with an unknown exception"); + + const auto outputs = mlms->infer(inputs, helper.getExtra()); + + auto* const output_tensors = response->mutable_output_tensors()->mutable_tensors(); + for (const auto& kv : *outputs) { + auto& emplaced = (*output_tensors)[kv.first]; + mlmodel_details::copy_sdk_tensor_to_api_tensor(kv.second, &emplaced); } - } catch (...) { - std::abort(); - } + + return ::grpc::Status(); + }); } ::grpc::Status MLModelServiceServer::Metadata( ::grpc::ServerContext* context, const ::viam::service::mlmodel::v1::MetadataRequest* request, - ::viam::service::mlmodel::v1::MetadataResponse* response) noexcept try { - if (!request) { - return {::grpc::StatusCode::INVALID_ARGUMENT, "Called [Metadata] without a request"}; - }; - - std::shared_ptr rb = resource_manager()->resource(request->name()); - if (!rb) { - return {grpc::UNKNOWN, "resource not found: " + request->name()}; - } - - std::shared_ptr mlms = std::dynamic_pointer_cast(rb); - AttributeMap extra; - if (request->has_extra()) { - extra = struct_to_map(request->extra()); - } - auto md = mlms->metadata(extra); - - auto& metadata_pb = *response->mutable_metadata(); - *metadata_pb.mutable_name() = std::move(md.name); - *metadata_pb.mutable_type() = std::move(md.type); - *metadata_pb.mutable_description() = std::move(md.description); - - const auto pack_tensor_info = [](auto& target, - const std::vector& source) { - target.Reserve(source.size()); - for (auto&& s : source) { - auto& new_entry = *target.Add(); - *new_entry.mutable_name() = std::move(s.name); - *new_entry.mutable_description() = std::move(s.description); - - const auto* string_for_data_type = - MLModelService::tensor_info::data_type_to_string(s.data_type); - if (!string_for_data_type) { - std::ostringstream message; - message << "Served MLModelService returned an unknown data type with value `" + ::viam::service::mlmodel::v1::MetadataResponse* response) noexcept { + return make_service_helper( + "MLModelServiceServer::Metadata", this, request)([&](auto& helper, auto& mlms) { + auto md = mlms->metadata(helper.getExtra()); + + auto& metadata_pb = *response->mutable_metadata(); + *metadata_pb.mutable_name() = std::move(md.name); + *metadata_pb.mutable_type() = std::move(md.type); + *metadata_pb.mutable_description() = std::move(md.description); + + const auto pack_tensor_info = [&helper]( + auto& target, + const std::vector& source) { + target.Reserve(source.size()); + for (auto&& s : source) { + auto& new_entry = *target.Add(); + *new_entry.mutable_name() = std::move(s.name); + *new_entry.mutable_description() = std::move(s.description); + + const auto* string_for_data_type = + MLModelService::tensor_info::data_type_to_string(s.data_type); + if (!string_for_data_type) { + std::ostringstream message; + message + << "Served MLModelService returned an unknown data type with value `" << static_cast< std::underlying_type::type>( s.data_type) << "` in its metadata"; - return ::grpc::Status{grpc::INTERNAL, message.str()}; - } - new_entry.set_data_type(string_for_data_type); - auto& shape = *new_entry.mutable_shape(); - // This would be nicer as `Reserve/Assign`, but older - // protubuf lacks Assign. The implementation of `Assign` - // is just `Clear/Add` though, so do that instead. - shape.Clear(); - shape.Reserve(s.shape.size()); - shape.Add(s.shape.begin(), s.shape.end()); - auto& associated_files = *new_entry.mutable_associated_files(); - associated_files.Reserve(s.associated_files.size()); - for (auto&& af : s.associated_files) { - auto& new_af = *associated_files.Add(); - *new_af.mutable_name() = std::move(af.name); - *new_af.mutable_description() = std::move(af.description); - switch (af.label_type) { - case MLModelService::tensor_info::file::k_label_type_tensor_value: - new_af.set_label_type( - ::viam::service::mlmodel::v1::LABEL_TYPE_TENSOR_VALUE); - break; - case MLModelService::tensor_info::file::k_label_type_tensor_axis: - new_af.set_label_type(::viam::service::mlmodel::v1::LABEL_TYPE_TENSOR_AXIS); - break; - default: - // In practice this shouldn't really happen - // since we shouldn't see an MLMS instance - // that we are serving return metadata - // containing values not contained in the - // enumeration. If it does, we just map it to - // unspecified - the client is likely to - // interpret it as an error. - new_af.set_label_type(::viam::service::mlmodel::v1::LABEL_TYPE_UNSPECIFIED); - break; + return helper.fail(grpc::INTERNAL, message.str().c_str()); + } + new_entry.set_data_type(string_for_data_type); + auto& shape = *new_entry.mutable_shape(); + // This would be nicer as `Reserve/Assign`, but older + // protubuf lacks Assign. The implementation of `Assign` + // is just `Clear/Add` though, so do that instead. + shape.Clear(); + shape.Reserve(s.shape.size()); + shape.Add(s.shape.begin(), s.shape.end()); + auto& associated_files = *new_entry.mutable_associated_files(); + associated_files.Reserve(s.associated_files.size()); + for (auto&& af : s.associated_files) { + auto& new_af = *associated_files.Add(); + *new_af.mutable_name() = std::move(af.name); + *new_af.mutable_description() = std::move(af.description); + switch (af.label_type) { + case MLModelService::tensor_info::file::k_label_type_tensor_value: + new_af.set_label_type( + ::viam::service::mlmodel::v1::LABEL_TYPE_TENSOR_VALUE); + break; + case MLModelService::tensor_info::file::k_label_type_tensor_axis: + new_af.set_label_type( + ::viam::service::mlmodel::v1::LABEL_TYPE_TENSOR_AXIS); + break; + default: + // In practice this shouldn't really happen + // since we shouldn't see an MLMS instance + // that we are serving return metadata + // containing values not contained in the + // enumeration. If it does, we just map it to + // unspecified - the client is likely to + // interpret it as an error. + new_af.set_label_type( + ::viam::service::mlmodel::v1::LABEL_TYPE_UNSPECIFIED); + break; + } + } + if (s.extra) { + *new_entry.mutable_extra() = map_to_struct(s.extra); } } - if (s.extra) { - *new_entry.mutable_extra() = map_to_struct(s.extra); - } - } - return ::grpc::Status(); - }; - - auto status = pack_tensor_info(*metadata_pb.mutable_input_info(), md.inputs); - if (!status.ok()) { - return status; - } - - return pack_tensor_info(*metadata_pb.mutable_output_info(), md.outputs); -} catch (...) { - try { - try { - throw; - } catch (const std::exception& ex) { - return ::grpc::Status(grpc::INTERNAL, - std::string("[Metadata]: Failed with exception: ") + ex.what()); - } catch (...) { - return ::grpc::Status(grpc::INTERNAL, "[Metadata]: Failed with an unknown exception"); + return ::grpc::Status(); + }; + + auto status = pack_tensor_info(*metadata_pb.mutable_input_info(), md.inputs); + if (!status.ok()) { + return status; } - } catch (...) { - std::abort(); - } + + return pack_tensor_info(*metadata_pb.mutable_output_info(), md.outputs); + }); } } // namespace sdk