in thrift/lib/cpp2/async/RocketClientChannel.cpp [221:312]
FOLLY_NODISCARD folly::exception_wrapper processFirstResponse(
ResponseRpcMetadata& metadata,
std::unique_ptr<folly::IOBuf>& payload,
Handler& handler) {
if (auto payloadMetadataRef = metadata.payloadMetadata_ref()) {
const auto isProxiedResponse =
metadata.proxiedPayloadMetadata_ref().has_value();
switch (payloadMetadataRef->getType()) {
case PayloadMetadata::responseMetadata:
payload = handler.handleReply(std::move(payload));
break;
case PayloadMetadata::exceptionMetadata: {
auto& exceptionMetadataBase =
payloadMetadataRef->get_exceptionMetadata();
auto otherMetadataRef = metadata.otherMetadata_ref();
if (!otherMetadataRef) {
otherMetadataRef.emplace();
}
auto exceptionNameRef = exceptionMetadataBase.name_utf8_ref();
auto exceptionWhatRef = exceptionMetadataBase.what_utf8_ref();
if (auto exceptionMetadataRef = exceptionMetadataBase.metadata_ref()) {
auto metaType = exceptionMetadataRef->getType();
switch (metaType) {
case PayloadExceptionMetadata::declaredException:
if (exceptionNameRef) {
(*otherMetadataRef)[isProxiedResponse ? "puex" : "uex"] =
*exceptionNameRef;
}
if (exceptionWhatRef) {
(*otherMetadataRef)[isProxiedResponse ? "puexw" : "uexw"] =
*exceptionWhatRef;
}
if (auto dExClass = exceptionMetadataRef->declaredException_ref()
->errorClassification_ref()) {
auto metaStr =
apache::thrift::detail::serializeErrorClassification(
*dExClass);
(*otherMetadataRef)[std::string(detail::kHeaderExMeta)] =
std::move(metaStr);
}
payload = handler.handleReply(std::move(payload));
break;
case PayloadExceptionMetadata::proxyException:
(*otherMetadataRef)
[isProxiedResponse ? "servicerouter:sr_error"
: "servicerouter:sr_internal_error"] =
protocol::base64Encode(payload->coalesce());
payload = handler.handleException(
TApplicationException(exceptionWhatRef.value_or("")));
break;
default:
switch (metaType) {
case PayloadExceptionMetadata::DEPRECATED_appClientException:
(*otherMetadataRef)[isProxiedResponse ? "pex" : "ex"] =
kAppClientErrorCode;
break;
case PayloadExceptionMetadata::appUnknownException:
if (auto ec = exceptionMetadataRef->appUnknownException_ref()
->errorClassification_ref()) {
if (ec->blame_ref() &&
*ec->blame_ref() == ErrorBlame::CLIENT) {
(*otherMetadataRef)[isProxiedResponse ? "pex" : "ex"] =
kAppClientErrorCode;
}
}
break;
default:;
}
if (exceptionNameRef) {
(*otherMetadataRef)[isProxiedResponse ? "puex" : "uex"] =
*exceptionNameRef;
}
if (exceptionWhatRef) {
(*otherMetadataRef)[isProxiedResponse ? "puexw" : "uexw"] =
*exceptionWhatRef;
}
payload = handler.handleException(
TApplicationException(exceptionWhatRef.value_or("")));
}
} else {
return TApplicationException("Missing payload exception metadata");
}
break;
}
default:
return TApplicationException("Invalid payload metadata type");
}
}
return {};
}