or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

connection-management.mdcookies.mderror-handling.mdhttp-api.mdhttp-clients.mdindex.mdinterceptors.mdtesting-mocking.mdutilities.mdweb-standards.md

error-handling.mddocs/

0

# Error Handling

1

2

Comprehensive error hierarchy covering all HTTP operation failure modes. Undici provides specific error types for different failure scenarios to enable precise error handling and debugging.

3

4

## Capabilities

5

6

### Base Error Class

7

8

```typescript { .api }

9

/**

10

* Base class for all Undici errors

11

*/

12

class UndiciError extends Error {

13

name: string;

14

code: string;

15

16

constructor(message?: string);

17

}

18

```

19

20

### Connection Errors

21

22

Errors related to establishing and maintaining connections.

23

24

```typescript { .api }

25

/**

26

* Thrown when connection establishment times out

27

*/

28

class ConnectTimeoutError extends UndiciError {

29

name: "ConnectTimeoutError";

30

code: "UND_ERR_CONNECT_TIMEOUT";

31

}

32

33

/**

34

* Thrown when socket-level errors occur

35

*/

36

class SocketError extends UndiciError {

37

name: "SocketError";

38

code: "UND_ERR_SOCKET";

39

socket: {

40

localAddress?: string;

41

localPort?: number;

42

remoteAddress?: string;

43

remotePort?: number;

44

};

45

}

46

47

/**

48

* Thrown when client is destroyed unexpectedly

49

*/

50

class ClientDestroyedError extends UndiciError {

51

name: "ClientDestroyedError";

52

code: "UND_ERR_DESTROYED";

53

}

54

55

/**

56

* Thrown when client is closed unexpectedly

57

*/

58

class ClientClosedError extends UndiciError {

59

name: "ClientClosedError";

60

code: "UND_ERR_CLOSED";

61

}

62

63

/**

64

* Thrown when secure proxy connection fails

65

*/

66

class SecureProxyConnectionError extends UndiciError {

67

name: "SecureProxyConnectionError";

68

code: "UND_ERR_PRX_TLS";

69

cause?: Error;

70

}

71

```

72

73

**Usage Examples:**

74

75

```typescript

76

import {

77

Client,

78

ConnectTimeoutError,

79

SocketError,

80

ClientDestroyedError

81

} from "undici-types";

82

83

const client = new Client("https://unreliable.example.com", {

84

headersTimeout: 5000

85

});

86

87

try {

88

const response = await client.request({

89

path: "/api/data",

90

method: "GET"

91

});

92

} catch (error) {

93

if (error instanceof ConnectTimeoutError) {

94

console.error("Connection timed out:", error.message);

95

// Implement retry logic or fallback

96

} else if (error instanceof SocketError) {

97

console.error("Socket error:", error.message);

98

console.error("Connection details:", error.socket);

99

// Log connection details for debugging

100

} else if (error instanceof ClientDestroyedError) {

101

console.error("Client was destroyed:", error.message);

102

// Create new client instance

103

}

104

}

105

```

106

107

### Timeout Errors

108

109

Errors related to various timeout scenarios during HTTP operations.

110

111

```typescript { .api }

112

/**

113

* Thrown when response headers are not received within timeout

114

*/

115

class HeadersTimeoutError extends UndiciError {

116

name: "HeadersTimeoutError";

117

code: "UND_ERR_HEADERS_TIMEOUT";

118

}

119

120

/**

121

* Thrown when response body is not received within timeout

122

*/

123

class BodyTimeoutError extends UndiciError {

124

name: "BodyTimeoutError";

125

code: "UND_ERR_BODY_TIMEOUT";

126

}

127

128

/**

129

* Thrown when headers exceed maximum size limit

130

*/

131

class HeadersOverflowError extends UndiciError {

132

name: "HeadersOverflowError";

133

code: "UND_ERR_HEADERS_OVERFLOW";

134

}

135

136

/**

137

* Thrown when response size exceeds maximum limit

138

*/

139

class ResponseExceededMaxSizeError extends UndiciError {

140

name: "ResponseExceededMaxSizeError";

141

code: "UND_ERR_RES_EXCEEDED_MAX_SIZE";

142

maxSize: number;

143

}

144

```

145

146

**Usage Examples:**

147

148

```typescript

149

import {

150

request,

151

HeadersTimeoutError,

152

BodyTimeoutError,

153

ResponseExceededMaxSizeError

154

} from "undici-types";

155

156

try {

157

const response = await request("https://slow-api.example.com/large-data", {

158

headersTimeout: 10000,

159

bodyTimeout: 30000

160

});

161

162

const data = await response.body.text();

163

} catch (error) {

164

if (error instanceof HeadersTimeoutError) {

165

console.error("Headers not received in time");

166

// Retry with longer timeout or different endpoint

167

} else if (error instanceof BodyTimeoutError) {

168

console.error("Body not received in time");

169

// Switch to streaming approach or increase timeout

170

} else if (error instanceof ResponseExceededMaxSizeError) {

171

console.error(`Response too large: ${error.maxSize} bytes`);

172

// Use streaming or pagination instead

173

}

174

}

175

```

176

177

### Request/Response Errors

178

179

Errors related to request processing and response handling.

180

181

```typescript { .api }

182

/**

183

* Thrown when request is aborted

184

*/

185

class RequestAbortedError extends UndiciError {

186

name: "RequestAbortedError";

187

code: "UND_ERR_ABORTED";

188

}

189

190

/**

191

* Thrown for general response errors

192

*/

193

class ResponseError extends UndiciError {

194

constructor(

195

message: string,

196

code: number,

197

options: {

198

headers?: IncomingHttpHeaders | string[] | null;

199

body?: null | Record<string, any> | string;

200

}

201

);

202

203

name: "ResponseError";

204

code: "UND_ERR_RESPONSE";

205

statusCode: number;

206

body: null | Record<string, any> | string;

207

headers: IncomingHttpHeaders | string[] | null;

208

}

209

210

/**

211

* Thrown for specific HTTP status code errors

212

*/

213

class ResponseStatusCodeError extends UndiciError {

214

constructor(

215

message?: string,

216

statusCode?: number,

217

headers?: IncomingHttpHeaders | string[] | null,

218

body?: null | Record<string, any> | string

219

);

220

221

name: "ResponseStatusCodeError";

222

code: "UND_ERR_RESPONSE_STATUS_CODE";

223

body: null | Record<string, any> | string;

224

status: number;

225

statusCode: number;

226

headers: IncomingHttpHeaders | string[] | null;

227

}

228

229

/**

230

* Thrown when request retry fails after maximum attempts

231

*/

232

class RequestRetryError extends UndiciError {

233

constructor(

234

message: string,

235

statusCode: number,

236

headers?: IncomingHttpHeaders | string[] | null,

237

body?: null | Record<string, any> | string

238

);

239

240

name: "RequestRetryError";

241

code: "UND_ERR_REQ_RETRY";

242

statusCode: number;

243

data: {

244

count: number;

245

};

246

headers: Record<string, string | string[]>;

247

}

248

249

/**

250

* Thrown when request content length doesn't match actual body size

251

*/

252

class RequestContentLengthMismatchError extends UndiciError {

253

name: "RequestContentLengthMismatchError";

254

code: "UND_ERR_REQ_CONTENT_LENGTH_MISMATCH";

255

}

256

257

/**

258

* Thrown when response content length doesn't match actual body size

259

*/

260

class ResponseContentLengthMismatchError extends UndiciError {

261

name: "ResponseContentLengthMismatchError";

262

code: "UND_ERR_RES_CONTENT_LENGTH_MISMATCH";

263

}

264

```

265

266

**Usage Examples:**

267

268

```typescript

269

import {

270

request,

271

RequestAbortedError,

272

ResponseStatusCodeError,

273

ResponseContentLengthMismatchError

274

} from "undici-types";

275

276

// Request with AbortController

277

const controller = new AbortController();

278

setTimeout(() => controller.abort(), 5000);

279

280

try {

281

const response = await request("https://api.example.com/slow-endpoint", {

282

signal: controller.signal,

283

throwOnError: true // Enable automatic status code error throwing

284

});

285

286

const data = await response.body.json();

287

} catch (error) {

288

if (error instanceof RequestAbortedError) {

289

console.error("Request was aborted");

290

// Handle cancellation

291

} else if (error instanceof ResponseStatusCodeError) {

292

console.error(`HTTP ${error.status}: ${error.statusText}`);

293

console.error("Response body:", error.body);

294

console.error("Response headers:", error.headers);

295

296

// Handle specific status codes

297

if (error.status === 401) {

298

// Handle authentication error

299

} else if (error.status === 429) {

300

// Handle rate limiting

301

const retryAfter = error.headers['retry-after'];

302

console.log(`Retry after: ${retryAfter} seconds`);

303

}

304

} else if (error instanceof ResponseContentLengthMismatchError) {

305

console.error("Response content length mismatch - possible truncated response");

306

// Retry request or handle partial data

307

}

308

}

309

```

310

311

### Validation Errors

312

313

Errors related to input validation and argument checking.

314

315

```typescript { .api }

316

/**

317

* Thrown when invalid arguments are provided

318

*/

319

class InvalidArgumentError extends UndiciError {

320

name: "InvalidArgumentError";

321

code: "UND_ERR_INVALID_ARG";

322

}

323

324

/**

325

* Thrown when invalid return values are encountered

326

*/

327

class InvalidReturnValueError extends UndiciError {

328

name: "InvalidReturnValueError";

329

code: "UND_ERR_INVALID_RETURN_VALUE";

330

}

331

332

/**

333

* Thrown when functionality is not supported

334

*/

335

class NotSupportedError extends UndiciError {

336

name: "NotSupportedError";

337

code: "UND_ERR_NOT_SUPPORTED";

338

}

339

```

340

341

**Usage Examples:**

342

343

```typescript

344

import {

345

Client,

346

InvalidArgumentError,

347

NotSupportedError

348

} from "undici-types";

349

350

try {

351

// This might throw InvalidArgumentError for invalid URL

352

const client = new Client("invalid-url");

353

354

// This might throw InvalidArgumentError for invalid method

355

await client.request({

356

path: "/api/data",

357

method: "INVALID_METHOD" as any

358

});

359

} catch (error) {

360

if (error instanceof InvalidArgumentError) {

361

console.error("Invalid argument provided:", error.message);

362

// Validate inputs before making requests

363

} else if (error instanceof NotSupportedError) {

364

console.error("Feature not supported:", error.message);

365

// Use alternative approach

366

}

367

}

368

```

369

370

### Pool and Agent Errors

371

372

Errors specific to connection pools and agents.

373

374

```typescript { .api }

375

/**

376

* Thrown when balanced pool has no available upstreams

377

*/

378

class BalancedPoolMissingUpstreamError extends UndiciError {

379

name: "BalancedPoolMissingUpstreamError";

380

code: "UND_ERR_BPL_MISSING_UPSTREAM";

381

}

382

383

/**

384

* Thrown on HTTP parsing errors

385

*/

386

class HTTPParserError extends UndiciError {

387

name: "HTTPParserError";

388

code: "UND_ERR_PARSER";

389

bytesParsed: number;

390

}

391

392

/**

393

* Thrown on informational status code errors (1xx)

394

*/

395

class InformationalError extends UndiciError {

396

name: "InformationalError";

397

code: "UND_ERR_INFO";

398

status: number;

399

statusText: string;

400

headers: Record<string, string | string[]>;

401

}

402

```

403

404

**Usage Examples:**

405

406

```typescript

407

import {

408

BalancedPool,

409

BalancedPoolMissingUpstreamError,

410

HTTPParserError

411

} from "undici-types";

412

413

// Balanced pool example

414

const pool = new BalancedPool([]);

415

416

try {

417

await pool.request({

418

path: "/api/data",

419

method: "GET"

420

});

421

} catch (error) {

422

if (error instanceof BalancedPoolMissingUpstreamError) {

423

console.error("No upstreams available in balanced pool");

424

// Add upstreams or use fallback

425

pool.addUpstream("https://backup.example.com");

426

} else if (error instanceof HTTPParserError) {

427

console.error("HTTP parsing error:", error.message);

428

console.error("Bytes parsed:", error.bytesParsed);

429

// Log for debugging malformed responses

430

}

431

}

432

```

433

434

### Retry Errors

435

436

Errors related to retry operations.

437

438

```typescript { .api }

439

/**

440

* Thrown when request retry fails after all attempts

441

*/

442

class RequestRetryError extends UndiciError {

443

name: "RequestRetryError";

444

code: "UND_ERR_REQ_RETRY";

445

statusCode: number;

446

data: {

447

count: number;

448

maxCount: number;

449

};

450

cause?: Error;

451

}

452

```

453

454

**Usage Examples:**

455

456

```typescript

457

import {

458

RetryAgent,

459

Agent,

460

RequestRetryError

461

} from "undici-types";

462

463

const retryAgent = new RetryAgent(new Agent(), {

464

retry: 3,

465

maxTimeout: 30000

466

});

467

468

try {

469

const response = await retryAgent.request({

470

origin: "https://unreliable-api.example.com",

471

path: "/api/data",

472

method: "GET"

473

});

474

} catch (error) {

475

if (error instanceof RequestRetryError) {

476

console.error(`Request failed after ${error.data.count} attempts`);

477

console.error(`Max attempts: ${error.data.maxCount}`);

478

console.error(`Final status: ${error.statusCode}`);

479

console.error(`Underlying cause:`, error.cause);

480

481

// Handle final failure

482

// Maybe try alternative endpoint or return cached data

483

}

484

}

485

```

486

487

## Error Namespace

488

489

All errors are also available through the errors namespace:

490

491

```typescript { .api }

492

namespace errors {

493

const UndiciError: typeof UndiciError;

494

const ConnectTimeoutError: typeof ConnectTimeoutError;

495

const HeadersTimeoutError: typeof HeadersTimeoutError;

496

const HeadersOverflowError: typeof HeadersOverflowError;

497

const BodyTimeoutError: typeof BodyTimeoutError;

498

const ResponseError: typeof ResponseError;

499

const ResponseStatusCodeError: typeof ResponseStatusCodeError;

500

const InvalidArgumentError: typeof InvalidArgumentError;

501

const InvalidReturnValueError: typeof InvalidReturnValueError;

502

const RequestAbortedError: typeof RequestAbortedError;

503

const InformationalError: typeof InformationalError;

504

const RequestContentLengthMismatchError: typeof RequestContentLengthMismatchError;

505

const ResponseContentLengthMismatchError: typeof ResponseContentLengthMismatchError;

506

const ClientDestroyedError: typeof ClientDestroyedError;

507

const ClientClosedError: typeof ClientClosedError;

508

const SocketError: typeof SocketError;

509

const NotSupportedError: typeof NotSupportedError;

510

const BalancedPoolMissingUpstreamError: typeof BalancedPoolMissingUpstreamError;

511

const HTTPParserError: typeof HTTPParserError;

512

const ResponseExceededMaxSizeError: typeof ResponseExceededMaxSizeError;

513

const RequestRetryError: typeof RequestRetryError;

514

const SecureProxyConnectionError: typeof SecureProxyConnectionError;

515

}

516

```

517

518

**Usage Examples:**

519

520

```typescript

521

import { errors } from "undici-types";

522

523

// Use errors namespace

524

try {

525

// Some HTTP operation

526

} catch (error) {

527

if (error instanceof errors.ConnectTimeoutError) {

528

// Handle connection timeout

529

} else if (error instanceof errors.ResponseStatusCodeError) {

530

// Handle HTTP status errors

531

}

532

}

533

534

// Error type checking utility

535

function isUndiciError(error: unknown): error is UndiciError {

536

return error instanceof errors.UndiciError;

537

}

538

539

function handleHttpError(error: unknown) {

540

if (!isUndiciError(error)) {

541

throw error; // Re-throw non-Undici errors

542

}

543

544

switch (error.code) {

545

case "UND_ERR_CONNECT_TIMEOUT":

546

return "Connection timed out - check network connectivity";

547

case "UND_ERR_RESPONSE_STATUS_CODE":

548

return `HTTP error: ${(error as errors.ResponseStatusCodeError).status}`;

549

case "UND_ERR_ABORTED":

550

return "Request was cancelled";

551

default:

552

return `Undici error: ${error.message}`;

553

}

554

}

555

```