or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-operations.mdbranch-management.mdcommit-operations.mdconfiguration.mderror-handling.mdindex.mdobject-operations.mdreference-management.mdremote-operations.mdrepository-operations.mdworking-directory.md
tile.json

error-handling.mddocs/

0

# Error Handling

1

2

isomorphic-git provides a comprehensive set of error classes for different failure conditions.

3

4

## Error Classes

5

6

### Core Errors

7

8

```javascript { .api }

9

/**

10

* Base error class for all isomorphic-git errors

11

*/

12

class BaseError extends Error {

13

name: string;

14

code: string;

15

data: any;

16

}

17

18

/**

19

* Reference or object not found

20

*/

21

class NotFoundError extends BaseError {

22

constructor(what: string);

23

}

24

25

/**

26

* Invalid reference name

27

*/

28

class InvalidRefNameError extends BaseError {

29

constructor(ref: string);

30

}

31

32

/**

33

* Invalid object ID format

34

*/

35

class InvalidOidError extends BaseError {

36

constructor(value: string);

37

}

38

39

/**

40

* Invalid file path

41

*/

42

class InvalidFilepathError extends BaseError {

43

constructor(filepath: string);

44

}

45

46

/**

47

* Unsafe file path (potential security issue)

48

*/

49

class UnsafeFilepathError extends BaseError {

50

constructor(filepath: string);

51

}

52

53

/**

54

* Required parameter missing

55

*/

56

class MissingParameterError extends BaseError {

57

constructor(parameter: string);

58

}

59

60

/**

61

* Required name parameter missing

62

*/

63

class MissingNameError extends BaseError {

64

constructor();

65

}

66

67

/**

68

* Ambiguous reference (multiple matches)

69

*/

70

class AmbiguousError extends BaseError {

71

constructor(nouns: string[], matches: string[]);

72

}

73

74

/**

75

* Object or reference already exists

76

*/

77

class AlreadyExistsError extends BaseError {

78

constructor(noun: string, where: string, name?: string);

79

}

80

81

/**

82

* Internal library error

83

*/

84

class InternalError extends BaseError {

85

constructor(message: string);

86

}

87

```

88

89

### Checkout and Merge Errors

90

91

```javascript { .api }

92

/**

93

* Checkout would overwrite local changes

94

*/

95

class CheckoutConflictError extends BaseError {

96

constructor(filepaths: string[]);

97

}

98

99

/**

100

* Merge conflict occurred

101

*/

102

class MergeConflictError extends BaseError {

103

constructor(filepaths: string[]);

104

}

105

106

/**

107

* Merge operation not supported for this scenario

108

*/

109

class MergeNotSupportedError extends BaseError {

110

constructor();

111

}

112

113

/**

114

* Repository has unmerged paths

115

*/

116

class UnmergedPathsError extends BaseError {

117

constructor(filepaths: string[]);

118

}

119

120

/**

121

* Fast-forward merge not possible

122

*/

123

class FastForwardError extends BaseError {

124

constructor();

125

}

126

```

127

128

### Remote Operation Errors

129

130

```javascript { .api }

131

/**

132

* HTTP request error

133

*/

134

class HttpError extends BaseError {

135

constructor(statusCode: number, statusMessage: string, response: string);

136

}

137

138

/**

139

* Git push operation failed

140

*/

141

class GitPushError extends BaseError {

142

constructor(prettyDetails: string, result: any);

143

}

144

145

/**

146

* Push rejected by remote server

147

*/

148

class PushRejectedError extends BaseError {

149

constructor(reason: string);

150

}

151

152

/**

153

* Empty response from server

154

*/

155

class EmptyServerResponseError extends BaseError {

156

constructor();

157

}

158

159

/**

160

* Smart HTTP protocol error

161

*/

162

class SmartHttpError extends BaseError {

163

constructor(preview: string, response: string);

164

}

165

166

/**

167

* Remote capability not supported

168

*/

169

class RemoteCapabilityError extends BaseError {

170

constructor(capability: string, remote: string);

171

}

172

173

/**

174

* Unknown transport protocol

175

*/

176

class UnknownTransportError extends BaseError {

177

constructor(url: string);

178

}

179

180

/**

181

* URL parsing error

182

*/

183

class UrlParseError extends BaseError {

184

constructor(url: string);

185

}

186

187

/**

188

* No refspec configured for push/pull

189

*/

190

class NoRefspecError extends BaseError {

191

constructor(remote: string);

192

}

193

```

194

195

### Repository State Errors

196

197

```javascript { .api }

198

/**

199

* Required commit not fetched from remote

200

*/

201

class CommitNotFetchedError extends BaseError {

202

constructor(ref: string, oid: string);

203

}

204

205

/**

206

* No commit found (empty repository)

207

*/

208

class NoCommitError extends BaseError {

209

constructor();

210

}

211

212

/**

213

* Multiple .git directories found

214

*/

215

class MultipleGitError extends BaseError {

216

constructor(gitdirs: string[]);

217

}

218

219

/**

220

* Maximum recursion depth reached

221

*/

222

class MaxDepthError extends BaseError {

223

constructor(depth: number);

224

}

225

226

/**

227

* Object type mismatch

228

*/

229

class ObjectTypeError extends BaseError {

230

constructor(oid: string, actual: string, expected: string);

231

}

232

233

/**

234

* Parsing error for Git objects or references

235

*/

236

class ParseError extends BaseError {

237

constructor(expected: string, actual: string);

238

}

239

240

/**

241

* Index reset error

242

*/

243

class IndexResetError extends BaseError {

244

constructor(filepath: string);

245

}

246

```

247

248

### User Interaction Errors

249

250

```javascript { .api }

251

/**

252

* User canceled the operation

253

*/

254

class UserCanceledError extends BaseError {

255

constructor();

256

}

257

```

258

259

## Usage Examples

260

261

### Basic Error Handling

262

263

```javascript

264

import git, { Errors } from "isomorphic-git";

265

import fs from "fs";

266

267

try {

268

await git.checkout({

269

fs,

270

dir: "/path/to/repo",

271

ref: "nonexistent-branch"

272

});

273

} catch (error) {

274

if (error instanceof Errors.NotFoundError) {

275

console.log("Branch not found:", error.data);

276

} else {

277

console.log("Unexpected error:", error.message);

278

}

279

}

280

```

281

282

### Specific Error Handling

283

284

```javascript

285

import git, { Errors } from "isomorphic-git";

286

import fs from "fs";

287

288

try {

289

await git.checkout({

290

fs,

291

dir: "/path/to/repo",

292

ref: "main"

293

});

294

} catch (error) {

295

switch (error.constructor) {

296

case Errors.CheckoutConflictError:

297

console.log("Cannot checkout - would overwrite:", error.data.filepaths);

298

// Offer to stash or commit changes

299

break;

300

301

case Errors.NotFoundError:

302

console.log("Branch not found:", error.data);

303

// Offer to create branch or list available branches

304

break;

305

306

case Errors.InvalidRefNameError:

307

console.log("Invalid branch name:", error.data.ref);

308

break;

309

310

default:

311

console.log("Checkout failed:", error.message);

312

}

313

}

314

```

315

316

### Network Error Handling

317

318

```javascript

319

import git, { Errors } from "isomorphic-git";

320

import http from "isomorphic-git/http/node";

321

import fs from "fs";

322

323

try {

324

await git.push({

325

fs,

326

http,

327

dir: "/path/to/repo",

328

remote: "origin",

329

ref: "main"

330

});

331

} catch (error) {

332

if (error instanceof Errors.HttpError) {

333

switch (error.data.statusCode) {

334

case 401:

335

console.log("Authentication required");

336

break;

337

case 403:

338

console.log("Permission denied");

339

break;

340

case 404:

341

console.log("Repository not found");

342

break;

343

default:

344

console.log(`HTTP error ${error.data.statusCode}: ${error.data.statusMessage}`);

345

}

346

} else if (error instanceof Errors.PushRejectedError) {

347

console.log("Push rejected:", error.data.reason);

348

console.log("Try pulling latest changes first");

349

} else if (error instanceof Errors.GitPushError) {

350

console.log("Push failed:", error.data.prettyDetails);

351

} else {

352

console.log("Push error:", error.message);

353

}

354

}

355

```

356

357

### Merge Conflict Handling

358

359

```javascript

360

import git, { Errors } from "isomorphic-git";

361

import fs from "fs";

362

363

try {

364

const result = await git.merge({

365

fs,

366

dir: "/path/to/repo",

367

theirs: "feature-branch"

368

});

369

370

if (result.conflicts && result.conflicts.length > 0) {

371

console.log("Merge conflicts in:", result.conflicts);

372

console.log("Please resolve conflicts and commit");

373

} else {

374

console.log("Merge completed successfully");

375

}

376

} catch (error) {

377

if (error instanceof Errors.MergeConflictError) {

378

console.log("Merge conflicts detected in:", error.data.filepaths);

379

console.log("Resolve conflicts manually, then:");

380

console.log("1. git add <resolved-files>");

381

console.log("2. git commit");

382

} else if (error instanceof Errors.MergeNotSupportedError) {

383

console.log("This type of merge is not supported");

384

console.log("Try a different merge strategy");

385

} else {

386

console.log("Merge failed:", error.message);

387

}

388

}

389

```

390

391

### Clone Error Handling

392

393

```javascript

394

import git, { Errors } from "isomorphic-git";

395

import http from "isomorphic-git/http/node";

396

import fs from "fs";

397

398

try {

399

await git.clone({

400

fs,

401

http,

402

dir: "/path/to/repo",

403

url: "https://github.com/user/repo.git"

404

});

405

} catch (error) {

406

if (error instanceof Errors.HttpError) {

407

if (error.data.statusCode === 404) {

408

console.log("Repository not found or private");

409

} else {

410

console.log(`Network error: ${error.data.statusCode}`);

411

}

412

} else if (error instanceof Errors.AlreadyExistsError) {

413

console.log("Directory already exists and is not empty");

414

} else if (error instanceof Errors.UrlParseError) {

415

console.log("Invalid repository URL:", error.data.url);

416

} else {

417

console.log("Clone failed:", error.message);

418

}

419

}

420

```

421

422

### Configuration Error Handling

423

424

```javascript

425

import git, { Errors } from "isomorphic-git";

426

import fs from "fs";

427

428

try {

429

const userName = await git.getConfig({

430

fs,

431

dir: "/path/to/repo",

432

path: "user.name"

433

});

434

console.log("User name:", userName);

435

} catch (error) {

436

if (error instanceof Errors.NotFoundError) {

437

console.log("Configuration not found - setting default");

438

await git.setConfig({

439

fs,

440

dir: "/path/to/repo",

441

path: "user.name",

442

value: "Default User"

443

});

444

} else {

445

console.log("Configuration error:", error.message);

446

}

447

}

448

```

449

450

### File System Error Handling

451

452

```javascript

453

import git, { Errors } from "isomorphic-git";

454

import fs from "fs";

455

456

try {

457

await git.add({

458

fs,

459

dir: "/path/to/repo",

460

filepath: "nonexistent/file.txt"

461

});

462

} catch (error) {

463

if (error instanceof Errors.NotFoundError) {

464

console.log("File not found:", error.data);

465

} else if (error instanceof Errors.InvalidFilepathError) {

466

console.log("Invalid file path:", error.data.filepath);

467

} else if (error instanceof Errors.UnsafeFilepathError) {

468

console.log("Unsafe file path detected:", error.data.filepath);

469

} else {

470

console.log("Add failed:", error.message);

471

}

472

}

473

```

474

475

## Error Information

476

477

Most errors include additional data in the `data` property:

478

479

```javascript

480

import git, { Errors } from "isomorphic-git";

481

import fs from "fs";

482

483

try {

484

// Some operation that fails

485

await git.resolveRef({

486

fs,

487

dir: "/path/to/repo",

488

ref: "ambiguous-ref"

489

});

490

} catch (error) {

491

console.log("Error name:", error.name);

492

console.log("Error code:", error.code);

493

console.log("Error message:", error.message);

494

console.log("Error data:", error.data);

495

console.log("Stack trace:", error.stack);

496

}

497

```

498

499

## Best Practices

500

501

### 1. Always Handle Expected Errors

502

503

```javascript

504

// Good: Handle expected error conditions

505

try {

506

await git.checkout({ fs, dir, ref: userInput });

507

} catch (error) {

508

if (error instanceof Errors.NotFoundError) {

509

// Handle missing branch gracefully

510

console.log(`Branch '${userInput}' not found`);

511

return;

512

}

513

throw error; // Re-throw unexpected errors

514

}

515

```

516

517

### 2. Provide User-Friendly Messages

518

519

```javascript

520

// Good: Convert technical errors to user-friendly messages

521

try {

522

await git.push({ fs, http, dir, remote: "origin", ref: "main" });

523

} catch (error) {

524

let userMessage;

525

526

if (error instanceof Errors.HttpError && error.data.statusCode === 401) {

527

userMessage = "Authentication failed. Please check your credentials.";

528

} else if (error instanceof Errors.PushRejectedError) {

529

userMessage = "Push rejected. Please pull the latest changes first.";

530

} else {

531

userMessage = `Push failed: ${error.message}`;

532

}

533

534

console.log(userMessage);

535

}

536

```

537

538

### 3. Log Detailed Error Information

539

540

```javascript

541

// Good: Log technical details for debugging

542

try {

543

await someGitOperation();

544

} catch (error) {

545

// User-friendly message

546

console.log("Operation failed:", getUserFriendlyMessage(error));

547

548

// Technical details for logs

549

console.error("Technical details:", {

550

error: error.name,

551

code: error.code,

552

data: error.data,

553

stack: error.stack

554

});

555

}

556

```