or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

batch-operations.mdcaching.mdchat-sessions.mdclient-configuration.mdcontent-generation.mdembeddings-tokens.mderror-handling.mdfile-search-stores.mdfiles-management.mdimage-operations.mdindex.mdlive-sessions.mdmodel-tuning.mdoperations.mdtools-functions.mdtypes-reference.mdvideo-generation.md

error-handling.mddocs/

0

# Error Handling

1

2

Exception hierarchy and error handling patterns for the Google GenAI SDK. All exceptions are unchecked (extend RuntimeException).

3

4

## Core Imports

5

6

```java

7

import com.google.genai.errors.ApiException;

8

import com.google.genai.errors.ClientException;

9

import com.google.genai.errors.ServerException;

10

import com.google.genai.errors.GenAiIOException;

11

```

12

13

## Exception Hierarchy

14

15

```

16

RuntimeException

17

├── ApiException (base for API errors)

18

│ ├── ClientException (4xx errors)

19

│ └── ServerException (5xx errors)

20

└── GenAiIOException (I/O and SDK errors)

21

```

22

23

## ApiException

24

25

Base class for all API-related errors.

26

27

```java { .api }

28

package com.google.genai.errors;

29

30

public class ApiException extends RuntimeException {

31

public ApiException(int code, String status, String message);

32

33

public int code();

34

public String status();

35

public String message();

36

37

public static void throwFromResponse(Response response);

38

}

39

```

40

41

**Usage:**

42

43

```java

44

try {

45

GenerateContentResponse response = client.models.generateContent(

46

"gemini-2.0-flash", "Hello", null);

47

} catch (ApiException e) {

48

System.err.println("API Error " + e.code() + ": " + e.message());

49

System.err.println("Status: " + e.status());

50

}

51

```

52

53

## ClientException

54

55

Client-side errors (HTTP 4xx status codes). Indicates issues with the request such as invalid parameters, authentication failures, or rate limiting.

56

57

```java { .api }

58

package com.google.genai.errors;

59

60

public final class ClientException extends ApiException {

61

public ClientException(int code, String status, String message);

62

}

63

```

64

65

**Common Status Codes:**

66

- 400 - Bad Request (invalid parameters)

67

- 401 - Unauthorized (invalid API key)

68

- 403 - Forbidden (insufficient permissions)

69

- 404 - Not Found (resource doesn't exist)

70

- 429 - Too Many Requests (rate limited)

71

72

**Usage:**

73

74

```java

75

try {

76

GenerateContentResponse response = client.models.generateContent(

77

"invalid-model", "Hello", null);

78

} catch (ClientException e) {

79

if (e.code() == 400) {

80

System.err.println("Bad request: " + e.message());

81

} else if (e.code() == 401) {

82

System.err.println("Authentication failed");

83

} else if (e.code() == 429) {

84

System.err.println("Rate limited, retry after delay");

85

}

86

}

87

```

88

89

## ServerException

90

91

Server-side errors (HTTP 5xx status codes). Indicates issues on Google's servers.

92

93

```java { .api }

94

package com.google.genai.errors;

95

96

public final class ServerException extends ApiException {

97

public ServerException(int code, String status, String message);

98

}

99

```

100

101

**Common Status Codes:**

102

- 500 - Internal Server Error

103

- 502 - Bad Gateway

104

- 503 - Service Unavailable

105

- 504 - Gateway Timeout

106

107

**Usage:**

108

109

```java

110

try {

111

GenerateContentResponse response = client.models.generateContent(

112

"gemini-2.0-flash", "Hello", null);

113

} catch (ServerException e) {

114

System.err.println("Server error " + e.code() + ": " + e.message());

115

// Consider retry with exponential backoff

116

}

117

```

118

119

## GenAiIOException

120

121

I/O and general SDK exceptions including network errors, file operations, and serialization issues.

122

123

```java { .api }

124

package com.google.genai.errors;

125

126

public class GenAiIOException extends RuntimeException {

127

public GenAiIOException(String message);

128

public GenAiIOException(String message, Throwable cause);

129

public GenAiIOException(Throwable cause);

130

}

131

```

132

133

**Usage:**

134

135

```java

136

try {

137

File file = client.files.upload("path/to/file.jpg", null);

138

} catch (GenAiIOException e) {

139

System.err.println("I/O error: " + e.getMessage());

140

if (e.getCause() != null) {

141

System.err.println("Caused by: " + e.getCause());

142

}

143

}

144

```

145

146

## Error Handling Patterns

147

148

### Basic Try-Catch

149

150

```java

151

import com.google.genai.errors.ApiException;

152

153

try {

154

GenerateContentResponse response = client.models.generateContent(

155

"gemini-2.0-flash",

156

"Hello",

157

null

158

);

159

System.out.println(response.text());

160

} catch (ApiException e) {

161

System.err.println("Error: " + e.message());

162

}

163

```

164

165

### Specific Exception Handling

166

167

```java

168

import com.google.genai.errors.ClientException;

169

import com.google.genai.errors.ServerException;

170

import com.google.genai.errors.GenAiIOException;

171

172

try {

173

GenerateContentResponse response = client.models.generateContent(

174

"gemini-2.0-flash", "Hello", null);

175

} catch (ClientException e) {

176

// Handle client errors (4xx)

177

System.err.println("Client error: " + e.code());

178

} catch (ServerException e) {

179

// Handle server errors (5xx)

180

System.err.println("Server error: " + e.code());

181

} catch (GenAiIOException e) {

182

// Handle I/O errors

183

System.err.println("I/O error: " + e.getMessage());

184

}

185

```

186

187

### Rate Limiting with Retry

188

189

```java

190

import java.util.concurrent.TimeUnit;

191

192

int maxRetries = 3;

193

int retryCount = 0;

194

GenerateContentResponse response = null;

195

196

while (retryCount < maxRetries) {

197

try {

198

response = client.models.generateContent(

199

"gemini-2.0-flash", "Hello", null);

200

break; // Success

201

} catch (ClientException e) {

202

if (e.code() == 429 && retryCount < maxRetries - 1) {

203

retryCount++;

204

long waitMs = (long) Math.pow(2, retryCount) * 1000;

205

System.err.println("Rate limited, waiting " + waitMs + "ms");

206

TimeUnit.MILLISECONDS.sleep(waitMs);

207

} else {

208

throw e;

209

}

210

}

211

}

212

```

213

214

### Server Error Retry

215

216

```java

217

int maxRetries = 3;

218

GenerateContentResponse response = null;

219

220

for (int attempt = 0; attempt < maxRetries; attempt++) {

221

try {

222

response = client.models.generateContent(

223

"gemini-2.0-flash", "Hello", null);

224

break;

225

} catch (ServerException e) {

226

if (attempt == maxRetries - 1) {

227

throw e; // Last attempt failed

228

}

229

long waitMs = (long) Math.pow(2, attempt) * 1000;

230

System.err.println("Server error, retrying after " + waitMs + "ms");

231

Thread.sleep(waitMs);

232

}

233

}

234

```

235

236

### File Upload Error Handling

237

238

```java

239

import java.io.File as JavaFile;

240

241

try {

242

JavaFile localFile = new JavaFile("path/to/file.jpg");

243

244

if (!localFile.exists()) {

245

throw new IllegalArgumentException("File not found");

246

}

247

248

if (localFile.length() > 2L * 1024 * 1024 * 1024) {

249

throw new IllegalArgumentException("File too large (max 2GB)");

250

}

251

252

File uploadedFile = client.files.upload(localFile, null);

253

System.out.println("Uploaded: " + uploadedFile.name().orElse("N/A"));

254

255

} catch (GenAiIOException e) {

256

System.err.println("Upload failed: " + e.getMessage());

257

} catch (ApiException e) {

258

System.err.println("API error: " + e.code() + " - " + e.message());

259

}

260

```

261

262

### Streaming Error Handling

263

264

```java

265

try (ResponseStream<GenerateContentResponse> stream =

266

client.models.generateContentStream("gemini-2.0-flash", "Tell a story", null)) {

267

268

for (GenerateContentResponse chunk : stream) {

269

try {

270

System.out.print(chunk.text());

271

} catch (Exception e) {

272

System.err.println("Error processing chunk: " + e.getMessage());

273

}

274

}

275

276

} catch (ApiException e) {

277

System.err.println("Streaming error: " + e.message());

278

}

279

```

280

281

### Async Error Handling

282

283

```java

284

import java.util.concurrent.CompletableFuture;

285

286

CompletableFuture<GenerateContentResponse> future =

287

client.async.models.generateContent("gemini-2.0-flash", "Hello", null);

288

289

future

290

.thenAccept(response -> {

291

System.out.println("Success: " + response.text());

292

})

293

.exceptionally(throwable -> {

294

if (throwable instanceof ClientException) {

295

ClientException e = (ClientException) throwable;

296

System.err.println("Client error: " + e.code());

297

} else if (throwable instanceof ServerException) {

298

ServerException e = (ServerException) throwable;

299

System.err.println("Server error: " + e.code());

300

} else {

301

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

302

}

303

return null;

304

});

305

```

306

307

### Safety Blocking Handling

308

309

```java

310

GenerateContentResponse response = client.models.generateContent(

311

"gemini-2.0-flash",

312

"Your prompt",

313

null

314

);

315

316

// Check if prompt was blocked

317

response.promptFeedback().ifPresent(feedback -> {

318

feedback.blockReason().ifPresent(reason -> {

319

System.err.println("Prompt blocked: " + reason);

320

feedback.safetyRatings().ifPresent(ratings -> {

321

for (SafetyRating rating : ratings) {

322

System.err.println("Category: " + rating.category().orElse("N/A"));

323

System.err.println("Probability: " + rating.probability().orElse("N/A"));

324

}

325

});

326

});

327

});

328

329

// Check if response was blocked

330

response.candidates().ifPresent(candidates -> {

331

if (!candidates.isEmpty()) {

332

Candidate first = candidates.get(0);

333

first.finishReason().ifPresent(reason -> {

334

if ("SAFETY".equals(reason)) {

335

System.err.println("Response blocked for safety");

336

first.safetyRatings().ifPresent(ratings -> {

337

// Process safety ratings

338

});

339

}

340

});

341

}

342

});

343

```

344

345

## Best Practices

346

347

### Centralized Error Handler

348

349

```java

350

public class ErrorHandler {

351

public static void handle(ApiException e) {

352

if (e instanceof ClientException) {

353

handleClientError((ClientException) e);

354

} else if (e instanceof ServerException) {

355

handleServerError((ServerException) e);

356

} else {

357

System.err.println("API error: " + e.message());

358

}

359

}

360

361

private static void handleClientError(ClientException e) {

362

switch (e.code()) {

363

case 400:

364

System.err.println("Invalid request: " + e.message());

365

break;

366

case 401:

367

System.err.println("Authentication failed");

368

break;

369

case 403:

370

System.err.println("Permission denied");

371

break;

372

case 429:

373

System.err.println("Rate limited");

374

break;

375

default:

376

System.err.println("Client error " + e.code() + ": " + e.message());

377

}

378

}

379

380

private static void handleServerError(ServerException e) {

381

System.err.println("Server error " + e.code() + ": " + e.message());

382

System.err.println("Please retry later");

383

}

384

}

385

386

// Usage

387

try {

388

GenerateContentResponse response = client.models.generateContent(...);

389

} catch (ApiException e) {

390

ErrorHandler.handle(e);

391

}

392

```

393

394

### Retry with Exponential Backoff

395

396

```java

397

public class RetryHelper {

398

public static <T> T withRetry(

399

Supplier<T> operation,

400

int maxRetries,

401

long initialDelayMs

402

) throws Exception {

403

int attempt = 0;

404

while (true) {

405

try {

406

return operation.get();

407

} catch (ServerException | ClientException e) {

408

boolean shouldRetry =

409

e instanceof ServerException ||

410

(e instanceof ClientException && ((ClientException) e).code() == 429);

411

412

if (!shouldRetry || attempt >= maxRetries - 1) {

413

throw e;

414

}

415

416

long delay = initialDelayMs * (long) Math.pow(2, attempt);

417

System.err.println("Retrying after " + delay + "ms");

418

Thread.sleep(delay);

419

attempt++;

420

}

421

}

422

}

423

}

424

425

// Usage

426

GenerateContentResponse response = RetryHelper.withRetry(

427

() -> client.models.generateContent("gemini-2.0-flash", "Hello", null),

428

3,

429

1000L

430

);

431

```

432

433

### Logging Errors

434

435

```java

436

import java.util.logging.Logger;

437

import java.util.logging.Level;

438

439

private static final Logger LOGGER = Logger.getLogger(MyClass.class.getName());

440

441

try {

442

GenerateContentResponse response = client.models.generateContent(

443

"gemini-2.0-flash", "Hello", null);

444

} catch (ApiException e) {

445

LOGGER.log(Level.SEVERE, "API error: code=" + e.code() +

446

", status=" + e.status() + ", message=" + e.message(), e);

447

} catch (GenAiIOException e) {

448

LOGGER.log(Level.SEVERE, "I/O error: " + e.getMessage(), e);

449

}

450

```

451