or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mderror-handling.mdimage-processing.mdindex.mdupload.mdutilities.md

error-handling.mddocs/

0

# Error Handling

1

2

Comprehensive error handling system with specific error types for different failure scenarios and automatic retry mechanisms.

3

4

## Capabilities

5

6

### Error Types

7

8

The SDK provides a hierarchical error system for precise error handling and debugging.

9

10

```typescript { .api }

11

enum QiniuErrorName {

12

// Input validation errors

13

InvalidFile = 'InvalidFile',

14

InvalidToken = 'InvalidToken',

15

InvalidMetadata = 'InvalidMetadata',

16

InvalidChunkSize = 'InvalidChunkSize',

17

InvalidCustomVars = 'InvalidCustomVars',

18

NotAvailableUploadHost = 'NotAvailableUploadHost',

19

20

// Cache and resume functionality errors

21

ReadCacheFailed = 'ReadCacheFailed',

22

InvalidCacheData = 'InvalidCacheData',

23

WriteCacheFailed = 'WriteCacheFailed',

24

RemoveCacheFailed = 'RemoveCacheFailed',

25

26

// Image compression errors

27

GetCanvasContextFailed = 'GetCanvasContextFailed',

28

UnsupportedFileType = 'UnsupportedFileType',

29

30

// Browser environment errors

31

FileReaderReadFailed = 'FileReaderReadFailed',

32

NotAvailableXMLHttpRequest = 'NotAvailableXMLHttpRequest',

33

InvalidProgressEventTarget = 'InvalidProgressEventTarget',

34

35

// Network and server errors

36

RequestError = 'RequestError'

37

}

38

```

39

40

### Base Error Class

41

42

Foundation error class for all SDK errors.

43

44

```typescript { .api }

45

/**

46

* Base error class for all Qiniu SDK errors

47

*/

48

class QiniuError implements Error {

49

public stack: string | undefined;

50

51

constructor(public name: QiniuErrorName, public message: string);

52

}

53

```

54

55

**Usage Example:**

56

57

```typescript

58

import { QiniuError, QiniuErrorName } from "qiniu-js";

59

60

try {

61

// Some SDK operation

62

} catch (error) {

63

if (error instanceof QiniuError) {

64

switch (error.name) {

65

case QiniuErrorName.InvalidFile:

66

console.error('File validation failed:', error.message);

67

break;

68

case QiniuErrorName.InvalidToken:

69

console.error('Token is invalid or expired:', error.message);

70

break;

71

default:

72

console.error('SDK error:', error.message);

73

}

74

}

75

}

76

```

77

78

### Request Error Class

79

80

Specific error type for HTTP request failures with server response details.

81

82

```typescript { .api }

83

/**

84

* Error class for HTTP request failures

85

*/

86

class QiniuRequestError extends QiniuError {

87

/**

88

* Legacy property for error type identification

89

* @deprecated Use instanceof instead

90

*/

91

public isRequestError = true;

92

93

/** Server response data if available */

94

public data?: any;

95

96

constructor(

97

public code: number,

98

public reqId: string,

99

message: string,

100

data?: any

101

);

102

}

103

```

104

105

**Usage Example:**

106

107

```typescript

108

import { upload, QiniuRequestError } from "qiniu-js";

109

110

const subscription = upload(file, key, token).subscribe({

111

error: (error) => {

112

if (error instanceof QiniuRequestError) {

113

console.error(`Request failed with HTTP ${error.code}`);

114

console.error(`Request ID: ${error.reqId}`);

115

116

if (error.data) {

117

console.error('Server response:', error.data);

118

}

119

120

// Handle specific HTTP codes

121

switch (error.code) {

122

case 401:

123

console.error('Unauthorized - check your token');

124

break;

125

case 403:

126

console.error('Forbidden - insufficient permissions');

127

break;

128

case 413:

129

console.error('File too large');

130

break;

131

case 599:

132

console.error('Server timeout - will retry automatically');

133

break;

134

default:

135

console.error('Request error:', error.message);

136

}

137

}

138

}

139

});

140

```

141

142

### Network Error Class

143

144

Specialized error for network connectivity issues.

145

146

```typescript { .api }

147

/**

148

* Error class for network connectivity issues

149

* Covers CORS, certificate, DNS, and connection failures

150

*/

151

class QiniuNetworkError extends QiniuRequestError {

152

constructor(message: string, reqId?: string);

153

}

154

```

155

156

**Usage Example:**

157

158

```typescript

159

import { upload, QiniuNetworkError, QiniuRequestError } from "qiniu-js";

160

161

const subscription = upload(file, key, token).subscribe({

162

error: (error) => {

163

if (error instanceof QiniuNetworkError) {

164

console.error('Network connectivity issue:', error.message);

165

// Suggest user checks connection, firewall, etc.

166

showNetworkErrorMessage();

167

} else if (error instanceof QiniuRequestError) {

168

console.error('Server request failed:', error.message);

169

// Handle server-side errors

170

} else {

171

console.error('Other error:', error.message);

172

// Handle validation and other errors

173

}

174

}

175

});

176

```

177

178

## Error Handling Patterns

179

180

### Comprehensive Error Handling

181

182

Complete error handling strategy covering all error types.

183

184

```typescript

185

import {

186

upload,

187

QiniuError,

188

QiniuRequestError,

189

QiniuNetworkError,

190

QiniuErrorName

191

} from "qiniu-js";

192

193

function handleUpload(file: File, key: string, token: string) {

194

const subscription = upload(file, key, token, {

195

fname: file.name

196

}, {

197

retryCount: 3,

198

region: 'z0'

199

}).subscribe({

200

next: (progress) => {

201

updateProgressUI(progress.total.percent);

202

},

203

error: (error) => {

204

if (error instanceof QiniuNetworkError) {

205

// Network issues - suggest user actions

206

showErrorMessage('Network connection failed. Please check your internet connection and try again.');

207

logError('network', error);

208

209

} else if (error instanceof QiniuRequestError) {

210

// Server errors - handle based on HTTP code

211

const isRetryable = [502, 503, 504, 599].includes(error.code);

212

213

if (isRetryable) {

214

showErrorMessage('Server temporarily unavailable. The upload will retry automatically.');

215

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

216

showErrorMessage('Upload token expired. Please refresh and try again.');

217

refreshToken();

218

} else if (error.code === 413) {

219

showErrorMessage('File is too large for upload.');

220

} else {

221

showErrorMessage(`Upload failed: ${error.message}`);

222

}

223

224

logError('request', error, { code: error.code, reqId: error.reqId });

225

226

} else if (error instanceof QiniuError) {

227

// SDK validation and runtime errors

228

switch (error.name) {

229

case QiniuErrorName.InvalidFile:

230

showErrorMessage('Invalid file selected. Please choose a different file.');

231

break;

232

case QiniuErrorName.InvalidToken:

233

showErrorMessage('Upload token is invalid. Please refresh and try again.');

234

refreshToken();

235

break;

236

case QiniuErrorName.UnsupportedFileType:

237

showErrorMessage('File type not supported for compression.');

238

break;

239

case QiniuErrorName.GetCanvasContextFailed:

240

showErrorMessage('Image processing failed. Browser may not support required features.');

241

break;

242

default:

243

showErrorMessage(`Upload failed: ${error.message}`);

244

}

245

246

logError('sdk', error);

247

248

} else {

249

// Unexpected errors

250

showErrorMessage('An unexpected error occurred. Please try again.');

251

logError('unknown', error);

252

}

253

},

254

complete: (response) => {

255

showSuccessMessage('File uploaded successfully!');

256

console.log('Upload result:', response);

257

}

258

});

259

260

return subscription;

261

}

262

263

// Helper functions

264

function showErrorMessage(message: string) {

265

// Update UI with error message

266

document.getElementById('error-message').textContent = message;

267

}

268

269

function showSuccessMessage(message: string) {

270

// Update UI with success message

271

document.getElementById('success-message').textContent = message;

272

}

273

274

function updateProgressUI(percent: number) {

275

// Update progress bar

276

document.getElementById('progress-bar').style.width = `${percent}%`;

277

}

278

279

function logError(type: string, error: any, extra?: any) {

280

// Send error to logging service

281

console.error(`[${type}] Upload error:`, error, extra);

282

}

283

284

function refreshToken() {

285

// Request new token from server

286

// Implementation depends on your authentication system

287

}

288

```

289

290

### Retry Logic and Error Recovery

291

292

The SDK automatically handles retries for certain error conditions:

293

294

```typescript

295

// Errors that trigger automatic retry

296

const RETRY_CODE_LIST = [0, 502, 503, 504, 599, 406];

297

298

// Errors that cause host switching

299

const FREEZE_CODE_LIST = [0, 502, 503, 504, 599];

300

```

301

302

**Custom Retry Configuration:**

303

304

```typescript

305

import { upload } from "qiniu-js";

306

307

// Configure retry behavior

308

const uploadWithRetry = upload(file, key, token, {

309

fname: file.name

310

}, {

311

retryCount: 5, // Retry up to 5 times

312

region: 'z0'

313

}).subscribe({

314

error: (error) => {

315

if (error instanceof QiniuRequestError) {

316

console.log(`Failed after ${5} retry attempts`);

317

}

318

}

319

});

320

```

321

322

### Validation Error Prevention

323

324

Prevent common validation errors by checking inputs before upload:

325

326

```typescript

327

import { QiniuError, QiniuErrorName } from "qiniu-js";

328

329

function validateUploadInputs(file: File, token: string, putExtra?: any): string | null {

330

// File validation

331

if (!file || file.size === 0) {

332

return 'Please select a valid file';

333

}

334

335

if (file.size > 10000 * 1024 * 1024 * 1024) { // 10TB limit

336

return 'File size exceeds maximum limit of 10TB';

337

}

338

339

// Token validation

340

if (!token || typeof token !== 'string') {

341

return 'Upload token is required';

342

}

343

344

// Custom variables validation

345

if (putExtra?.customVars) {

346

for (const key of Object.keys(putExtra.customVars)) {

347

if (!key.startsWith('x:')) {

348

return `Custom variable key '${key}' must start with 'x:'`;

349

}

350

}

351

}

352

353

// Metadata validation

354

if (putExtra?.metadata) {

355

for (const key of Object.keys(putExtra.metadata)) {

356

if (!key.startsWith('x-qn-meta-')) {

357

return `Metadata key '${key}' must start with 'x-qn-meta-'`;

358

}

359

}

360

}

361

362

return null; // No validation errors

363

}

364

365

// Use validation before upload

366

function safeUpload(file: File, key: string, token: string, putExtra?: any) {

367

const validationError = validateUploadInputs(file, token, putExtra);

368

369

if (validationError) {

370

console.error('Validation failed:', validationError);

371

return;

372

}

373

374

return upload(file, key, token, putExtra);

375

}

376

```