Error Handling
A PDK call can fail at two different layers, and you must check both.
Transport errors (gRPC status). The server is unreachable, the call timed out, the request could not be parsed, and so on. In Python these raise
grpc.RpcError; in C++ the returnedgrpc::Statusis notok().Application errors (
response.status). The server received the request but could not do what you asked: the object does not exist, no workcell is loaded, the service is not licensed. Nothing is raised. The response comes back normally, with a non-zerostatus.code.
Warning
A response object always exists after a successful gRPC call, even when the
operation failed. Always check status.code.
The Status message
Most responses contain flexiv.pdk.common.Status status = 1:
Code |
Name |
Meaning |
|---|---|---|
0 |
|
Success. |
1 |
|
The named item does not exist. |
2 |
|
The request is malformed or a value is out of range. |
3 |
|
The server failed while executing the request. |
4 |
|
Preconditions are not met. Most often: no workcell is loaded. |
5 |
|
The service needs a license this computer does not have. |
status.message is optional and, when present, explains the failure in plain
language.
Recommended pattern
Python:
import grpc
from flexiv.pdk.workcell.workcell_service_pb2 import NameRequest
class PdkError(RuntimeError):
pass
def check(response, what: str):
"""Raises if a PDK response carries a failure status."""
status = getattr(response, "status", None)
if status is not None and status.code != 0:
raise PdkError(f"{what} failed: {status.message} (code {status.code})")
return response
try:
res = check(client.workcell.stub.Load(NameRequest(name="demo")), "Load workcell")
except grpc.RpcError as e:
print(f"gRPC {e.code().name}: {e.details()}")
except PdkError as e:
print(e)
C++:
bool ProtoStatusOk(const flexiv::pdk::common::Status& status)
{
return status.code() == flexiv::pdk::common::Status::OK;
}
grpc::ClientContext ctx;
flexiv::pdk::workcell::NameRequest req;
req.set_name("demo");
flexiv::pdk::workcell::WorkcellResponse res;
const grpc::Status s = client.workcell().stub->Load(&ctx, req, &res);
if (!s.ok()) {
std::cerr << "gRPC error: " << s.error_message() << "\n";
} else if (!ProtoStatusOk(res.status())) {
std::cerr << "Load failed: " << res.status().message() << "\n";
}
Exceptions to the pattern
Some
ReconstructionServiceandCameraServiceRPCs return a barecommon.Statusinstead of a response wrapper. Check.codeon the returned message itself.
Common failures
FAILED_PRECONDITIONfrom scene callsNo workcell is active. Create or load one first (Workcells).
PERMISSION_DENIEDThe service is licensed and this machine has no valid license for it. See Activate Licenses.
- gRPC
UNAVAILABLE The server is not running or not reachable at the target address.
- gRPC
INTERNALwith no details Usually stale generated stubs in a source install. See Troubleshooting.