Overview
useGit uses promise-based error handling. All Git operations return promises that:
Resolve with the command output (as a string) when successful
Reject with an Error object when the command fails
Basic Error Handling
Use standard try/catch blocks to handle errors:
import git from "use-git"
try {
await git . commit ( "Update feature" )
console . log ( "Commit successful" )
} catch ( error ) {
console . error ( "Commit failed:" , error . message )
}
Error Types
useGit generates two types of errors based on the failure mode:
Command Execution Errors
These occur when the Git command itself cannot be executed (e.g., Git not installed, spawn fails):
try {
await git . status ()
} catch ( error ) {
// Error message format:
// "Error executing command git status: <error details>"
console . error ( error . message )
}
Common causes:
Git is not installed
Git executable not in PATH
Permission issues
System resource limits
Command Failure Errors
These occur when Git executes but returns a non-zero exit code:
try {
await git . commit ( "Empty commit" ) // No staged changes
} catch ( error ) {
// Error message format:
// "Git command failed (exit <code>):\n<command>\n<stderr output>"
console . error ( error . message )
}
Common causes:
Invalid Git command or options
Repository state issues
Merge conflicts
Authentication failures
Pre-commit hooks failing
Error Message Structure
Error executing command git <command>: <error message>
Example:
Error executing command git status: spawn git ENOENT
Git command failed (exit <code>):
<command>
<stderr output>
Example:
Git command failed (exit 1):
commit -m Update feature
nothing to commit, working tree clean
Common Error Scenarios
Nothing to Commit
import git from "use-git"
try {
await git . commit ( "Update" )
} catch ( error ) {
if ( error . message . includes ( "nothing to commit" )) {
console . log ( "No changes to commit" )
} else {
throw error // Re-throw unexpected errors
}
}
Not a Git Repository
import { createGit } from "use-git"
const git = createGit ({ cwd: "/some/directory" })
try {
await git . status ()
} catch ( error ) {
if ( error . message . includes ( "not a git repository" )) {
console . log ( "Initializing new repository..." )
await git . init ()
} else {
throw error
}
}
Merge Conflicts
try {
await git . merge ( "feature-branch" )
} catch ( error ) {
if ( error . message . includes ( "CONFLICT" )) {
console . log ( "Merge conflicts detected" )
// Get list of conflicted files
const status = await git . status ([ "--short" ])
console . log ( status )
} else {
throw error
}
}
Authentication Failures
try {
await git . push ()
} catch ( error ) {
if (
error . message . includes ( "Authentication failed" ) ||
error . message . includes ( "Permission denied" )
) {
console . error ( "Git authentication failed. Check your credentials." )
} else {
throw error
}
}
Safe Operations
For operations where you want to check success/failure without throwing errors, some functions provide “safe” alternatives:
import { runCmdSafe } from "use-git/internal"
// Returns boolean instead of throwing
const success = await runCmdSafe ( "status" , [])
if ( success ) {
console . log ( "Status check passed" )
} else {
console . log ( "Status check failed" )
}
The runCmdSafe function is part of the internal API. It returns true if the command succeeds (exit code 0) and false otherwise, without throwing errors.
Validation Before Operations
Prevent errors by validating repository state first:
Check Repository Exists
import git from "use-git"
if ( await git . isRepo ()) {
await git . status ()
} else {
console . log ( "Not a Git repository" )
}
Check for Uncommitted Changes
const isDirty = await git . isDirty ()
if ( isDirty ) {
console . log ( "You have uncommitted changes" )
const proceed = await askUser ( "Continue anyway?" )
if ( ! proceed ) {
process . exit ( 0 )
}
}
Check for Staged Changes
const hasStagedDiff = await git . hasStagedDiff ()
if ( ! hasStagedDiff ) {
console . log ( "No staged changes to commit" )
} else {
await git . commit ( "Update files" )
}
Error Recovery Patterns
Retry Logic
async function retryOperation < T >(
operation : () => Promise < T >,
maxAttempts = 3 ,
) : Promise < T > {
for ( let attempt = 1 ; attempt <= maxAttempts ; attempt ++ ) {
try {
return await operation ()
} catch ( error ) {
if ( attempt === maxAttempts ) {
throw error
}
console . log ( `Attempt ${ attempt } failed, retrying...` )
await new Promise ( resolve => setTimeout ( resolve , 1000 ))
}
}
throw new Error ( "Max attempts reached" )
}
// Usage
try {
await retryOperation (() => git . push ())
} catch ( error ) {
console . error ( "Push failed after multiple attempts:" , error . message )
}
Graceful Degradation
async function getRepoInfo ( repoPath : string ) {
const git = createGit ({ cwd: repoPath })
const info = {
isRepo: false ,
branch: null ,
isDirty: false ,
lastCommit: null ,
}
try {
info . isRepo = await git . isRepo ()
if ( info . isRepo ) {
try {
info . branch = await git . currentBranch ()
} catch {
// Branch detection failed, continue anyway
}
try {
info . isDirty = await git . isDirty ()
} catch {
// Dirty check failed, continue anyway
}
}
} catch ( error ) {
console . warn ( "Failed to gather full repo info:" , error . message )
}
return info
}
Cleanup on Failure
import { createGit } from "use-git"
import { rm } from "node:fs/promises"
const tempPath = "/tmp/clone-test"
const git = createGit ({ cwd: tempPath })
try {
await git . clone ( "https://github.com/user/repo.git" , tempPath )
// Do something with the cloned repo
const status = await git . status ()
console . log ( status )
} catch ( error ) {
console . error ( "Operation failed:" , error . message )
// Cleanup partial clone
try {
await rm ( tempPath , { recursive: true , force: true })
} catch {
// Cleanup failed, but don't throw
console . warn ( "Failed to cleanup temporary directory" )
}
throw error
} finally {
// Always log completion
console . log ( "Operation completed" )
}
Debug Mode for Troubleshooting
Enable debug mode to see exactly what Git commands are being executed:
import { createGit } from "use-git"
const git = createGit ({ debug: true })
try {
await git . commit ( "Update" )
} catch ( error ) {
// Debug output will show:
// [use-git] DEBUG running: git commit -m Update
console . error ( error . message )
}
Debug mode is invaluable for understanding why commands fail. It shows the exact command being executed, making it easy to reproduce issues manually.
Type-Safe Error Handling
For TypeScript users, ensure proper error typing:
import git from "use-git"
try {
await git . commit ( "Update" )
} catch ( error ) {
// Type guard for Error objects
if ( error instanceof Error ) {
console . error ( error . message )
// Access error properties safely
if ( error . stack ) {
console . debug ( error . stack )
}
} else {
// Handle non-Error throws
console . error ( "Unknown error:" , error )
}
}
Best Practices
Always Handle Errors
// Bad: Unhandled rejection
await git . commit ( "Update" )
// Good: Explicit error handling
try {
await git . commit ( "Update" )
} catch ( error ) {
handleError ( error )
}
Provide Context in Error Messages
try {
await git . push ()
} catch ( error ) {
throw new Error (
`Failed to push changes to remote: ${ error . message } `
)
}
Don’t Swallow Errors
// Bad: Silent failure
try {
await git . commit ( "Update" )
} catch {
// Error ignored
}
// Good: Log or re-throw
try {
await git . commit ( "Update" )
} catch ( error ) {
console . error ( "Commit failed:" , error )
throw error // Or handle appropriately
}
Use Specific Error Checks
// Bad: Generic error handling
try {
await git . commit ( "Update" )
} catch ( error ) {
console . log ( "Something went wrong" )
}
// Good: Specific error identification
try {
await git . commit ( "Update" )
} catch ( error ) {
if ( error . message . includes ( "nothing to commit" )) {
console . log ( "No changes to commit" )
} else if ( error . message . includes ( "Author identity unknown" )) {
console . error ( "Git user not configured" )
} else {
console . error ( "Unexpected error:" , error . message )
}
}
Next Steps
Creating Git Instance Configure instances with debug mode
Working Directory Handle directory-related errors