or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cloud-storage.mdconfiguration.mderror-handling.mdimage-sources.mdindex.mdresults.mdtransformations.md

error-handling.mddocs/

0

# Error Handling

1

2

Comprehensive error types for different failure scenarios including authentication, client, server, and connection errors.

3

4

## Capabilities

5

6

### Error Class Hierarchy

7

8

Tinify provides a structured error hierarchy for different types of failures.

9

10

```typescript { .api }

11

/**

12

* Base error class for all Tinify errors

13

*/

14

class Error extends globalThis.Error {

15

/** HTTP status code if available */

16

status?: number;

17

18

/**

19

* Create a new Tinify error

20

* @param message - Error message

21

* @param type - Error type string

22

* @param status - HTTP status code

23

*/

24

constructor(message: string, type?: string, status?: number);

25

26

/**

27

* Factory method to create appropriate error subclass

28

* @param message - Error message

29

* @param type - Error type from API

30

* @param status - HTTP status code

31

* @returns Appropriate error subclass instance

32

*/

33

static create(message: string, type: string, status?: number): Error;

34

}

35

36

/**

37

* Account-related errors (authentication, billing, limits)

38

* Thrown for HTTP status codes 401 and 429

39

*/

40

class AccountError extends Error {}

41

42

/**

43

* Client-side errors (invalid input, bad requests)

44

* Thrown for HTTP status codes 400-499 (except 401, 429)

45

*/

46

class ClientError extends Error {}

47

48

/**

49

* Server-side errors (API service issues)

50

* Thrown for HTTP status codes 500-599

51

*/

52

class ServerError extends Error {}

53

54

/**

55

* Network connectivity errors

56

* Thrown for connection failures, timeouts, proxy issues

57

*/

58

class ConnectionError extends Error {}

59

```

60

61

### Account Errors

62

63

Handle authentication, billing, and API usage limit issues.

64

65

**Common Account Error Scenarios:**

66

67

- Invalid or missing API key

68

- Monthly compression limit exceeded

69

- Account suspension or billing issues

70

- Rate limiting (too many requests)

71

72

**Usage Examples:**

73

74

```typescript

75

const tinify = require("tinify");

76

77

// Invalid API key

78

tinify.key = "invalid-key";

79

80

try {

81

await tinify.fromFile("image.jpg").toFile("compressed.jpg");

82

} catch (error) {

83

if (error instanceof tinify.AccountError) {

84

if (error.status === 401) {

85

console.error("Invalid API key:", error.message);

86

// Prompt user to check their API key

87

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

88

console.error("Monthly limit exceeded:", error.message);

89

// Handle billing upgrade or wait for next month

90

}

91

}

92

}

93

94

// Check compression count to avoid limits

95

tinify.key = "valid-api-key";

96

97

try {

98

await tinify.validate();

99

console.log(`Compressions used: ${tinify.compressionCount}`);

100

101

if (tinify.compressionCount && tinify.compressionCount > 450) {

102

console.warn("Approaching monthly limit!");

103

}

104

} catch (error) {

105

if (error instanceof tinify.AccountError) {

106

console.error("Account validation failed:", error.message);

107

}

108

}

109

```

110

111

### Client Errors

112

113

Handle invalid input, unsupported formats, and malformed requests.

114

115

**Common Client Error Scenarios:**

116

117

- Invalid file format or corrupted image

118

- Unsupported transformation parameters

119

- Invalid URLs or file paths

120

- Malformed configuration options

121

122

**Usage Examples:**

123

124

```typescript

125

const tinify = require("tinify");

126

127

tinify.key = "your-api-key";

128

129

try {

130

// Invalid file path

131

await tinify.fromFile("nonexistent-file.jpg").toFile("output.jpg");

132

} catch (error) {

133

if (error instanceof tinify.ClientError) {

134

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

135

136

if (error.status === 400) {

137

console.error("Bad request - check input parameters");

138

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

139

console.error("Unsupported image format");

140

}

141

}

142

}

143

144

try {

145

// Invalid transformation options

146

await tinify.fromFile("image.jpg")

147

.resize({ method: "invalid-method", width: -100 })

148

.toFile("output.jpg");

149

} catch (error) {

150

if (error instanceof tinify.ClientError) {

151

console.error("Invalid resize options:", error.message);

152

}

153

}

154

155

try {

156

// Invalid URL

157

await tinify.fromUrl("not-a-valid-url").toFile("output.jpg");

158

} catch (error) {

159

if (error instanceof tinify.ClientError) {

160

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

161

}

162

}

163

```

164

165

### Server Errors

166

167

Handle temporary API service issues and server-side problems.

168

169

**Common Server Error Scenarios:**

170

171

- Temporary API service outages

172

- Server overload or maintenance

173

- Internal processing errors

174

175

**Usage Examples:**

176

177

```typescript

178

const tinify = require("tinify");

179

180

tinify.key = "your-api-key";

181

182

try {

183

await tinify.fromFile("image.jpg").toFile("compressed.jpg");

184

} catch (error) {

185

if (error instanceof tinify.ServerError) {

186

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

187

188

if (error.status === 500) {

189

console.error("Internal server error - try again later");

190

} else if (error.status === 502 || error.status === 503) {

191

console.error("Service temporarily unavailable");

192

}

193

194

// Implement retry logic for server errors

195

setTimeout(async () => {

196

try {

197

await tinify.fromFile("image.jpg").toFile("compressed.jpg");

198

console.log("Retry successful");

199

} catch (retryError) {

200

console.error("Retry failed:", retryError.message);

201

}

202

}, 5000);

203

}

204

}

205

```

206

207

### Connection Errors

208

209

Handle network connectivity, proxy, and timeout issues.

210

211

**Common Connection Error Scenarios:**

212

213

- Network connectivity problems

214

- Proxy configuration issues

215

- Request timeouts

216

- DNS resolution failures

217

218

**Usage Examples:**

219

220

```typescript

221

const tinify = require("tinify");

222

223

tinify.key = "your-api-key";

224

tinify.proxy = "http://proxy.example.com:8080";

225

226

try {

227

await tinify.fromFile("image.jpg").toFile("compressed.jpg");

228

} catch (error) {

229

if (error instanceof tinify.ConnectionError) {

230

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

231

232

// Check different potential causes

233

if (error.message.includes("ENOTFOUND")) {

234

console.error("DNS resolution failed - check network connectivity");

235

} else if (error.message.includes("ECONNREFUSED")) {

236

console.error("Connection refused - check proxy settings");

237

} else if (error.message.includes("timeout")) {

238

console.error("Request timeout - check network speed");

239

}

240

241

// Suggest troubleshooting steps

242

console.log("Troubleshooting suggestions:");

243

console.log("1. Check internet connectivity");

244

console.log("2. Verify proxy settings");

245

console.log("3. Try again without proxy");

246

247

// Retry without proxy

248

try {

249

tinify.proxy = "";

250

await tinify.fromFile("image.jpg").toFile("compressed.jpg");

251

console.log("Success without proxy");

252

} catch (retryError) {

253

console.error("Still failing without proxy:", retryError.message);

254

}

255

}

256

}

257

```

258

259

### Comprehensive Error Handling

260

261

Best practices for handling all error types in production applications.

262

263

**Usage Example:**

264

265

```typescript

266

const tinify = require("tinify");

267

268

tinify.key = "your-api-key";

269

270

async function processImage(inputPath: string, outputPath: string, maxRetries = 3): Promise<boolean> {

271

let retries = 0;

272

273

while (retries < maxRetries) {

274

try {

275

await tinify.fromFile(inputPath)

276

.resize({ method: "fit", width: 1200 })

277

.toFile(outputPath);

278

279

console.log(`Successfully processed: ${outputPath}`);

280

return true;

281

282

} catch (error) {

283

if (error instanceof tinify.AccountError) {

284

if (error.status === 401) {

285

console.error("Invalid API key - check configuration");

286

return false; // Don't retry for auth errors

287

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

288

console.error("Monthly limit exceeded");

289

return false; // Don't retry for limit errors

290

}

291

292

} else if (error instanceof tinify.ClientError) {

293

console.error(`Client error: ${error.message}`);

294

return false; // Don't retry for client errors

295

296

} else if (error instanceof tinify.ServerError) {

297

console.error(`Server error (attempt ${retries + 1}): ${error.message}`);

298

retries++;

299

300

if (retries < maxRetries) {

301

const delay = Math.pow(2, retries) * 1000; // Exponential backoff

302

console.log(`Retrying in ${delay}ms...`);

303

await new Promise(resolve => setTimeout(resolve, delay));

304

}

305

306

} else if (error instanceof tinify.ConnectionError) {

307

console.error(`Connection error (attempt ${retries + 1}): ${error.message}`);

308

retries++;

309

310

if (retries < maxRetries) {

311

const delay = 2000; // Fixed delay for connection errors

312

console.log(`Retrying in ${delay}ms...`);

313

await new Promise(resolve => setTimeout(resolve, delay));

314

}

315

316

} else {

317

console.error(`Unexpected error: ${error.message}`);

318

return false;

319

}

320

}

321

}

322

323

console.error(`Failed to process image after ${maxRetries} attempts`);

324

return false;

325

}

326

327

// Usage

328

const success = await processImage("input.jpg", "output.jpg");

329

if (!success) {

330

console.error("Image processing failed permanently");

331

}

332

```

333

334

### Error Status Codes

335

336

Common HTTP status codes and their corresponding error types:

337

338

**Account Errors:**

339

- `401`: Unauthorized (invalid API key)

340

- `429`: Too Many Requests (monthly limit exceeded)

341

342

**Client Errors:**

343

- `400`: Bad Request (invalid parameters)

344

- `415`: Unsupported Media Type (invalid image format)

345

346

**Server Errors:**

347

- `500`: Internal Server Error

348

- `502`: Bad Gateway

349

- `503`: Service Unavailable

350

351

**Connection Errors:**

352

- No status code (network-level failures)

353

354

**Error Inspection Example:**

355

356

```typescript

357

const tinify = require("tinify");

358

359

tinify.key = "your-api-key";

360

361

try {

362

await tinify.fromFile("image.jpg").toFile("compressed.jpg");

363

} catch (error) {

364

console.log(`Error type: ${error.constructor.name}`);

365

console.log(`Error message: ${error.message}`);

366

367

if (error.status) {

368

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

369

}

370

371

// Type-specific handling

372

switch (error.constructor.name) {

373

case 'AccountError':

374

console.log("Account-related issue");

375

break;

376

case 'ClientError':

377

console.log("Client-side issue");

378

break;

379

case 'ServerError':

380

console.log("Server-side issue");

381

break;

382

case 'ConnectionError':

383

console.log("Network connectivity issue");

384

break;

385

default:

386

console.log("Unknown error type");

387

}

388

}

389

```