or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

api-infrastructure.mdapps-cards.mdcloud-platform.mdcommon-types.mdindex.mdlongrunning-operations.mdrpc-status.md

rpc-status.mddocs/

0

# RPC Status and Error Handling

1

2

Standard error model and status codes for consistent error handling across gRPC services. Includes structured error details and context information for debugging and client error handling.

3

4

## Core Status Types

5

6

### Status

7

8

The canonical error model used across gRPC services.

9

10

```java { .api }

11

class Status {

12

int getCode();

13

String getMessage();

14

repeated Any getDetailsList();

15

16

static Status.Builder newBuilder();

17

Status.Builder toBuilder();

18

static Status parseFrom(byte[] data);

19

static Status parseFrom(InputStream input);

20

byte[] toByteArray();

21

}

22

23

interface StatusOrBuilder {

24

int getCode();

25

String getMessage();

26

java.util.List<com.google.protobuf.Any> getDetailsList();

27

int getDetailsCount();

28

com.google.protobuf.Any getDetails(int index);

29

}

30

```

31

32

### Code

33

34

Standard gRPC status codes indicating the error type.

35

36

```java { .api }

37

enum Code {

38

OK(0),

39

CANCELLED(1),

40

UNKNOWN(2),

41

INVALID_ARGUMENT(3),

42

DEADLINE_EXCEEDED(4),

43

NOT_FOUND(5),

44

ALREADY_EXISTS(6),

45

PERMISSION_DENIED(7),

46

RESOURCE_EXHAUSTED(8),

47

FAILED_PRECONDITION(9),

48

ABORTED(10),

49

OUT_OF_RANGE(11),

50

UNIMPLEMENTED(12),

51

INTERNAL(13),

52

UNAVAILABLE(14),

53

DATA_LOSS(15),

54

UNAUTHENTICATED(16);

55

56

int getNumber();

57

static Code forNumber(int value);

58

static Code valueOf(int value);

59

}

60

```

61

62

## Error Detail Types

63

64

### ErrorInfo

65

66

Structured error information with reason, domain, and metadata.

67

68

```java { .api }

69

class ErrorInfo {

70

String getReason();

71

String getDomain();

72

Struct getMetadata();

73

74

static ErrorInfo.Builder newBuilder();

75

}

76

```

77

78

### BadRequest

79

80

Details for field-level validation errors.

81

82

```java { .api }

83

class BadRequest {

84

repeated FieldViolation getFieldViolationsList();

85

86

static BadRequest.Builder newBuilder();

87

}

88

89

class BadRequest.FieldViolation {

90

String getField();

91

String getDescription();

92

93

static FieldViolation.Builder newBuilder();

94

}

95

```

96

97

### PreconditionFailure

98

99

Information about failed preconditions.

100

101

```java { .api }

102

class PreconditionFailure {

103

repeated Violation getViolationsList();

104

105

static PreconditionFailure.Builder newBuilder();

106

}

107

108

class PreconditionFailure.Violation {

109

String getType();

110

String getSubject();

111

String getDescription();

112

113

static Violation.Builder newBuilder();

114

}

115

```

116

117

### QuotaFailure

118

119

Details about quota violations.

120

121

```java { .api }

122

class QuotaFailure {

123

repeated Violation getViolationsList();

124

125

static QuotaFailure.Builder newBuilder();

126

}

127

128

class QuotaFailure.Violation {

129

String getSubject();

130

String getDescription();

131

132

static Violation.Builder newBuilder();

133

}

134

```

135

136

### RetryInfo

137

138

Information about retry timing for retryable errors.

139

140

```java { .api }

141

class RetryInfo {

142

Duration getRetryDelay();

143

144

static RetryInfo.Builder newBuilder();

145

}

146

```

147

148

### DebugInfo

149

150

Debug information for development and troubleshooting.

151

152

```java { .api }

153

class DebugInfo {

154

repeated String getStackEntriesList();

155

String getDetail();

156

157

static DebugInfo.Builder newBuilder();

158

}

159

```

160

161

### ResourceInfo

162

163

Information about the resource that caused the error.

164

165

```java { .api }

166

class ResourceInfo {

167

String getResourceType();

168

String getResourceName();

169

String getOwner();

170

String getDescription();

171

172

static ResourceInfo.Builder newBuilder();

173

}

174

```

175

176

### Help

177

178

Links and information for error resolution.

179

180

```java { .api }

181

class Help {

182

repeated Link getLinksList();

183

184

static Help.Builder newBuilder();

185

}

186

187

class Help.Link {

188

String getDescription();

189

String getUrl();

190

191

static Link.Builder newBuilder();

192

}

193

```

194

195

### LocalizedMessage

196

197

Localized error messages for user-facing errors.

198

199

```java { .api }

200

class LocalizedMessage {

201

String getLocale();

202

String getMessage();

203

204

static LocalizedMessage.Builder newBuilder();

205

}

206

```

207

208

## Context Information

209

210

### AttributeContext

211

212

Request context attributes for audit and debugging.

213

214

```java { .api }

215

class AttributeContext {

216

Request getRequest();

217

Response getResponse();

218

Resource getResource();

219

Peer getSource();

220

Peer getDestination();

221

222

static AttributeContext.Builder newBuilder();

223

}

224

225

class AttributeContext.Request {

226

String getId();

227

String getMethod();

228

Struct getHeaders();

229

String getPath();

230

String getHost();

231

String getScheme();

232

String getQuery();

233

Timestamp getTime();

234

long getSize();

235

String getProtocol();

236

String getReason();

237

Auth getAuth();

238

239

static Request.Builder newBuilder();

240

}

241

242

class AttributeContext.Response {

243

long getCode();

244

long getSize();

245

Struct getHeaders();

246

Timestamp getTime();

247

Duration getBackendLatency();

248

249

static Response.Builder newBuilder();

250

}

251

252

class AttributeContext.Peer {

253

String getIp();

254

long getPort();

255

Struct getLabels();

256

String getPrincipal();

257

String getRegionCode();

258

259

static Peer.Builder newBuilder();

260

}

261

```

262

263

## Usage Examples

264

265

### Creating Basic Status

266

267

```java

268

import com.google.rpc.Status;

269

import com.google.rpc.Code;

270

271

// Success status

272

Status success = Status.newBuilder()

273

.setCode(Code.OK.getNumber())

274

.setMessage("Operation completed successfully")

275

.build();

276

277

// Error status

278

Status error = Status.newBuilder()

279

.setCode(Code.INVALID_ARGUMENT.getNumber())

280

.setMessage("Invalid user ID provided")

281

.build();

282

```

283

284

### Creating Status with Error Details

285

286

```java

287

import com.google.rpc.BadRequest;

288

import com.google.rpc.ErrorInfo;

289

import com.google.protobuf.Any;

290

291

// Create field validation error

292

BadRequest.FieldViolation fieldError = BadRequest.FieldViolation.newBuilder()

293

.setField("email")

294

.setDescription("Invalid email format")

295

.build();

296

297

BadRequest badRequest = BadRequest.newBuilder()

298

.addFieldViolations(fieldError)

299

.build();

300

301

// Create error info

302

ErrorInfo errorInfo = ErrorInfo.newBuilder()

303

.setReason("INVALID_EMAIL_FORMAT")

304

.setDomain("myservice.googleapis.com")

305

.build();

306

307

// Pack details into Any messages

308

Any badRequestAny = Any.pack(badRequest);

309

Any errorInfoAny = Any.pack(errorInfo);

310

311

// Create status with details

312

Status detailedError = Status.newBuilder()

313

.setCode(Code.INVALID_ARGUMENT.getNumber())

314

.setMessage("Validation failed")

315

.addDetails(badRequestAny)

316

.addDetails(errorInfoAny)

317

.build();

318

```

319

320

### Handling Status Responses

321

322

```java

323

// Check if operation was successful

324

public void handleResponse(Status status) {

325

Code code = Code.forNumber(status.getCode());

326

327

switch (code) {

328

case OK:

329

System.out.println("Success: " + status.getMessage());

330

break;

331

332

case INVALID_ARGUMENT:

333

System.err.println("Invalid argument: " + status.getMessage());

334

handleValidationErrors(status.getDetailsList());

335

break;

336

337

case NOT_FOUND:

338

System.err.println("Resource not found: " + status.getMessage());

339

break;

340

341

case PERMISSION_DENIED:

342

System.err.println("Access denied: " + status.getMessage());

343

break;

344

345

case RESOURCE_EXHAUSTED:

346

System.err.println("Quota exceeded: " + status.getMessage());

347

handleRetry(status.getDetailsList());

348

break;

349

350

default:

351

System.err.println("Error " + code + ": " + status.getMessage());

352

}

353

}

354

355

private void handleValidationErrors(java.util.List<Any> details) {

356

for (Any detail : details) {

357

if (detail.is(BadRequest.class)) {

358

try {

359

BadRequest badRequest = detail.unpack(BadRequest.class);

360

for (BadRequest.FieldViolation violation : badRequest.getFieldViolationsList()) {

361

System.err.println("Field '" + violation.getField() + "': " + violation.getDescription());

362

}

363

} catch (InvalidProtocolBufferException e) {

364

System.err.println("Error unpacking BadRequest: " + e.getMessage());

365

}

366

}

367

}

368

}

369

370

private void handleRetry(java.util.List<Any> details) {

371

for (Any detail : details) {

372

if (detail.is(RetryInfo.class)) {

373

try {

374

RetryInfo retryInfo = detail.unpack(RetryInfo.class);

375

Duration delay = retryInfo.getRetryDelay();

376

long seconds = delay.getSeconds() + delay.getNanos() / 1_000_000_000L;

377

System.out.println("Retry after " + seconds + " seconds");

378

} catch (InvalidProtocolBufferException e) {

379

System.err.println("Error unpacking RetryInfo: " + e.getMessage());

380

}

381

}

382

}

383

}

384

```

385

386

### Exception Mapping

387

388

```java

389

import io.grpc.Status.Code as GrpcCode;

390

import io.grpc.StatusException;

391

392

// Convert between Proto Status and gRPC Status

393

public StatusException toGrpcException(com.google.rpc.Status protoStatus) {

394

GrpcCode grpcCode = GrpcCode.values()[protoStatus.getCode()];

395

io.grpc.Status grpcStatus = io.grpc.Status.fromCode(grpcCode)

396

.withDescription(protoStatus.getMessage());

397

398

return grpcStatus.asException();

399

}

400

401

// Create Proto Status from gRPC Status

402

public com.google.rpc.Status fromGrpcStatus(io.grpc.Status grpcStatus) {

403

return com.google.rpc.Status.newBuilder()

404

.setCode(grpcStatus.getCode().value())

405

.setMessage(grpcStatus.getDescription() != null ? grpcStatus.getDescription() : "")

406

.build();

407

}

408

```

409

410

## Common Status Code Usage

411

412

| Code | Usage | Retry? |

413

|------|-------|--------|

414

| `OK` | Success | No |

415

| `CANCELLED` | Request cancelled by client | No |

416

| `INVALID_ARGUMENT` | Invalid request parameters | No |

417

| `DEADLINE_EXCEEDED` | Request timeout | Yes |

418

| `NOT_FOUND` | Resource doesn't exist | No |

419

| `ALREADY_EXISTS` | Resource already exists | No |

420

| `PERMISSION_DENIED` | Access denied | No |

421

| `RESOURCE_EXHAUSTED` | Rate limited or quota exceeded | Yes |

422

| `FAILED_PRECONDITION` | System not in valid state | No |

423

| `UNAVAILABLE` | Service temporarily unavailable | Yes |

424

| `INTERNAL` | Internal server error | No |

425

| `UNAUTHENTICATED` | Authentication required | No |

426

427

## Best Practices

428

429

1. **Use appropriate status codes**: Choose the most specific code that describes the error condition

430

2. **Provide meaningful messages**: Include actionable information in the message field

431

3. **Add structured details**: Use typed error details for programmatic error handling

432

4. **Include context**: Add relevant context information for debugging

433

5. **Handle retryable errors**: Implement proper retry logic for transient failures

434

6. **Localize messages**: Use LocalizedMessage for user-facing errors