feat(3p/nix/daemon): catch-all explicit Error-Status conversion
We wrap every server-side proto handler with a macro that catches exceptions and turns them into proper grpc error codes. For the time being, most exceptions map to INTERNAL, the existing mapping. Change-Id: Id6ed6a279b198ad185d32562f39000ccc15eadbf Reviewed-on: https://cl.tvl.fyi/c/depot/+/1599 Tested-by: BuildkiteCI Reviewed-by: glittershark <grfn@gws.fyi>
This commit is contained in:
parent
ae31f51dc8
commit
2344f8e528
2 changed files with 381 additions and 201 deletions
98
third_party/nix/src/libstore/rpc-store.cc
vendored
98
third_party/nix/src/libstore/rpc-store.cc
vendored
|
|
@ -3,6 +3,7 @@
|
|||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
#include <absl/status/status.h>
|
||||
#include <absl/strings/str_cat.h>
|
||||
#include <absl/strings/str_format.h>
|
||||
#include <google/protobuf/empty.pb.h>
|
||||
|
|
@ -52,14 +53,105 @@ T FillFrom(const U& src) {
|
|||
return result;
|
||||
}
|
||||
|
||||
constexpr absl::StatusCode GRPCStatusCodeToAbsl(grpc::StatusCode code) {
|
||||
switch (code) {
|
||||
case grpc::StatusCode::OK:
|
||||
return absl::StatusCode::kOk;
|
||||
case grpc::StatusCode::CANCELLED:
|
||||
return absl::StatusCode::kCancelled;
|
||||
case grpc::StatusCode::UNKNOWN:
|
||||
return absl::StatusCode::kUnknown;
|
||||
case grpc::StatusCode::INVALID_ARGUMENT:
|
||||
return absl::StatusCode::kInvalidArgument;
|
||||
case grpc::StatusCode::DEADLINE_EXCEEDED:
|
||||
return absl::StatusCode::kDeadlineExceeded;
|
||||
case grpc::StatusCode::NOT_FOUND:
|
||||
return absl::StatusCode::kNotFound;
|
||||
case grpc::StatusCode::ALREADY_EXISTS:
|
||||
return absl::StatusCode::kAlreadyExists;
|
||||
case grpc::StatusCode::PERMISSION_DENIED:
|
||||
return absl::StatusCode::kPermissionDenied;
|
||||
case grpc::StatusCode::UNAUTHENTICATED:
|
||||
return absl::StatusCode::kUnauthenticated;
|
||||
case grpc::StatusCode::RESOURCE_EXHAUSTED:
|
||||
return absl::StatusCode::kResourceExhausted;
|
||||
case grpc::StatusCode::FAILED_PRECONDITION:
|
||||
return absl::StatusCode::kFailedPrecondition;
|
||||
case grpc::StatusCode::ABORTED:
|
||||
return absl::StatusCode::kAborted;
|
||||
case grpc::StatusCode::OUT_OF_RANGE:
|
||||
return absl::StatusCode::kOutOfRange;
|
||||
case grpc::StatusCode::UNIMPLEMENTED:
|
||||
return absl::StatusCode::kUnimplemented;
|
||||
case grpc::StatusCode::INTERNAL:
|
||||
return absl::StatusCode::kInternal;
|
||||
case grpc::StatusCode::UNAVAILABLE:
|
||||
return absl::StatusCode::kUnavailable;
|
||||
case grpc::StatusCode::DATA_LOSS:
|
||||
return absl::StatusCode::kDataLoss;
|
||||
default:
|
||||
return absl::StatusCode::kInternal;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr absl::string_view GRPCStatusCodeDescription(grpc::StatusCode code) {
|
||||
switch (code) {
|
||||
case grpc::StatusCode::OK:
|
||||
return "OK";
|
||||
case grpc::StatusCode::CANCELLED:
|
||||
return "CANCELLED";
|
||||
case grpc::StatusCode::UNKNOWN:
|
||||
return "UNKNOWN";
|
||||
case grpc::StatusCode::INVALID_ARGUMENT:
|
||||
return "INVALID_ARGUMENT";
|
||||
case grpc::StatusCode::DEADLINE_EXCEEDED:
|
||||
return "DEADLINE_EXCEEDED";
|
||||
case grpc::StatusCode::NOT_FOUND:
|
||||
return "NOT_FOUND";
|
||||
case grpc::StatusCode::ALREADY_EXISTS:
|
||||
return "ALREADY_EXISTS";
|
||||
case grpc::StatusCode::PERMISSION_DENIED:
|
||||
return "PERMISSION_DENIED";
|
||||
case grpc::StatusCode::UNAUTHENTICATED:
|
||||
return "UNAUTHENTICATED";
|
||||
case grpc::StatusCode::RESOURCE_EXHAUSTED:
|
||||
return "RESOURCE_EXHAUSTED";
|
||||
case grpc::StatusCode::FAILED_PRECONDITION:
|
||||
return "FAILED_PRECONDITION";
|
||||
case grpc::StatusCode::ABORTED:
|
||||
return "ABORTED";
|
||||
case grpc::StatusCode::OUT_OF_RANGE:
|
||||
return "OUT_OF_RANGE";
|
||||
case grpc::StatusCode::UNIMPLEMENTED:
|
||||
return "UNIMPLEMENTED";
|
||||
case grpc::StatusCode::INTERNAL:
|
||||
return "INTERNAL";
|
||||
case grpc::StatusCode::UNAVAILABLE:
|
||||
return "UNAVAILABLE";
|
||||
case grpc::StatusCode::DATA_LOSS:
|
||||
return "DATA_LOSS";
|
||||
default:
|
||||
return "<BAD ERROR CODE>";
|
||||
};
|
||||
}
|
||||
|
||||
// TODO(grfn): Obviously this should go away and be replaced by StatusOr... but
|
||||
// that would require refactoring the entire store api, which we don't feel like
|
||||
// doing right now. We should at some point though
|
||||
void const RpcStore::SuccessOrThrow(const grpc::Status& status) const {
|
||||
if (!status.ok()) {
|
||||
throw Error(absl::StrFormat("Rpc call to %s failed (%d): %s ",
|
||||
uri_.value_or("unknown URI"),
|
||||
status.error_code(), status.error_message()));
|
||||
auto uri = uri_.value_or("unknown URI");
|
||||
switch (status.error_code()) {
|
||||
case grpc::StatusCode::UNIMPLEMENTED:
|
||||
throw Unsupported(
|
||||
absl::StrFormat("operation is not supported by store at %s: %s",
|
||||
uri, status.error_message()));
|
||||
default:
|
||||
throw Error(
|
||||
absl::StrFormat("Rpc call to %s failed (%s): %s ", uri,
|
||||
GRPCStatusCodeDescription(status.error_code()),
|
||||
status.error_message()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue