or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-interface.mdexception-handling.mdexperimental-features.mdhelper-interface.mdindex.md

exception-handling.mddocs/

0

# Exception Handling

1

2

PyExifTool provides a comprehensive exception hierarchy for different error conditions with detailed error information including exit codes, command output, and specific error contexts. All exceptions inherit from the base ExifToolException class for easy catch-all error handling.

3

4

## Capabilities

5

6

### Base Exception Classes

7

8

Foundation exception classes that provide common interfaces and are never raised directly.

9

10

```python { .api }

11

class ExifToolException(Exception):

12

"""

13

Generic base class for all ExifTool error classes.

14

Use this for catch-all exception handling.

15

"""

16

17

class ExifToolProcessStateError(ExifToolException):

18

"""

19

Base class for all errors related to invalid state of exiftool subprocess.

20

Covers scenarios where subprocess is running when it shouldn't be or vice versa.

21

"""

22

23

class ExifToolExecuteException(ExifToolException):

24

"""

25

Base exception class for all execute() associated errors.

26

Never returned directly but provides common interface for subclassed errors.

27

28

Attributes:

29

- returncode: int, exit status from exiftool command

30

- cmd: list, parameters sent to exiftool that caused error

31

- stdout: str, STDOUT stream from failed command

32

- stderr: str, STDERR stream from failed command

33

"""

34

35

def __init__(self, message, exit_status, cmd_stdout, cmd_stderr, params):

36

"""

37

Initialize execute exception with detailed error context.

38

39

Parameters:

40

- message: str, error description

41

- exit_status: int, command exit status

42

- cmd_stdout: str, command stdout output

43

- cmd_stderr: str, command stderr output

44

- params: list, command parameters that failed

45

"""

46

```

47

48

### Process State Exceptions

49

50

Exceptions raised when subprocess operations are attempted in invalid states.

51

52

```python { .api }

53

class ExifToolRunning(ExifToolProcessStateError):

54

"""

55

Raised when trying to modify settings while subprocess is running.

56

Common scenarios: changing executable path, encoding, or common_args while running.

57

"""

58

59

def __init__(self, message: str):

60

"""

61

Initialize with descriptive message.

62

63

Parameters:

64

- message: str, description of what operation was attempted

65

"""

66

67

class ExifToolNotRunning(ExifToolProcessStateError):

68

"""

69

Raised when trying to execute commands while subprocess is not running.

70

Common scenarios: calling execute() before run() or after terminate().

71

"""

72

73

def __init__(self, message: str):

74

"""

75

Initialize with descriptive message.

76

77

Parameters:

78

- message: str, description of what operation was attempted

79

"""

80

```

81

82

### Execute Exceptions

83

84

Exceptions raised during command execution with detailed error information.

85

86

```python { .api }

87

class ExifToolExecuteError(ExifToolExecuteException):

88

"""

89

Raised when execute() returns non-zero exit status.

90

Most common execution error - indicates exiftool command failed.

91

"""

92

93

def __init__(self, exit_status, cmd_stdout, cmd_stderr, params):

94

"""

95

Initialize with command execution details.

96

97

Parameters:

98

- exit_status: int, non-zero exit status from exiftool

99

- cmd_stdout: str, stdout from failed command

100

- cmd_stderr: str, stderr from failed command

101

- params: list, command parameters that failed

102

"""

103

104

class ExifToolOutputEmptyError(ExifToolExecuteException):

105

"""

106

Raised when execute_json() expects output but execute() returns none.

107

Indicates mismatch between expected JSON output and actual command behavior.

108

"""

109

110

def __init__(self, exit_status, cmd_stdout, cmd_stderr, params):

111

"""

112

Initialize with empty output context.

113

114

Parameters:

115

- exit_status: int, command exit status

116

- cmd_stdout: str, empty stdout that was expected to contain JSON

117

- cmd_stderr: str, stderr output

118

- params: list, command parameters that produced no output

119

"""

120

121

class ExifToolJSONInvalidError(ExifToolExecuteException):

122

"""

123

Raised when execute_json() receives invalid JSON from exiftool.

124

Indicates JSON parsing failure of exiftool output.

125

"""

126

127

def __init__(self, exit_status, cmd_stdout, cmd_stderr, params):

128

"""

129

Initialize with invalid JSON context.

130

131

Parameters:

132

- exit_status: int, command exit status

133

- cmd_stdout: str, stdout containing invalid JSON

134

- cmd_stderr: str, stderr output

135

- params: list, command parameters that produced invalid JSON

136

"""

137

```

138

139

### Other Exceptions

140

141

Specialized exceptions for specific error conditions.

142

143

```python { .api }

144

class ExifToolVersionError(ExifToolException):

145

"""

146

Raised when exiftool version requirements are not met.

147

PyExifTool requires exiftool version 12.15 or later for full functionality.

148

"""

149

150

class ExifToolTagNameError(ExifToolException):

151

"""

152

Raised when invalid tag names are detected by ExifToolHelper.

153

Only occurs when check_tag_names is enabled and invalid tag format is found.

154

"""

155

156

def __init__(self, bad_tag):

157

"""

158

Initialize with invalid tag name.

159

160

Parameters:

161

- bad_tag: str, the invalid tag name that was detected

162

"""

163

```

164

165

## Usage Examples

166

167

### Basic Exception Handling

168

169

```python

170

import exiftool

171

from exiftool.exceptions import ExifToolException, ExifToolExecuteError

172

173

try:

174

with exiftool.ExifToolHelper() as et:

175

metadata = et.get_metadata('nonexistent.jpg')

176

except ExifToolExecuteError as e:

177

print(f"Command failed with exit status {e.returncode}")

178

print(f"Error output: {e.stderr}")

179

print(f"Command: {' '.join(e.cmd)}")

180

except ExifToolException as e:

181

print(f"ExifTool error: {e}")

182

except Exception as e:

183

print(f"Unexpected error: {e}")

184

```

185

186

### Specific Exception Handling

187

188

```python

189

from exiftool.exceptions import (

190

ExifToolNotRunning,

191

ExifToolRunning,

192

ExifToolJSONInvalidError,

193

ExifToolTagNameError

194

)

195

196

et = exiftool.ExifTool()

197

198

try:

199

# This will raise ExifToolNotRunning

200

et.execute('-ver')

201

except ExifToolNotRunning as e:

202

print(f"Need to start subprocess first: {e}")

203

et.run()

204

205

try:

206

# This might raise ExifToolJSONInvalidError

207

result = et.execute_json('-invalid-json-command')

208

except ExifToolJSONInvalidError as e:

209

print(f"JSON parsing failed: {e}")

210

print(f"Raw output was: {e.stdout}")

211

212

try:

213

# This will raise ExifToolRunning

214

et.executable = '/different/path/exiftool'

215

except ExifToolRunning as e:

216

print(f"Cannot change settings while running: {e}")

217

218

et.terminate()

219

```

220

221

### Helper Class Exception Handling

222

223

```python

224

from exiftool.exceptions import ExifToolTagNameError

225

226

with exiftool.ExifToolHelper(check_tag_names=True) as et:

227

try:

228

# This will raise ExifToolTagNameError if tag format is invalid

229

et.get_tags('photo.jpg', ['Invalid:Tag:Format'])

230

except ExifToolTagNameError as e:

231

print(f"Invalid tag name: {e}")

232

233

try:

234

# Disable tag checking for this operation

235

et.check_tag_names = False

236

et.get_tags('photo.jpg', ['Invalid:Tag:Format']) # Won't raise error

237

except ExifToolExecuteError as e:

238

print(f"Command failed at exiftool level: {e}")

239

```

240

241

### Comprehensive Error Handling Pattern

242

243

```python

244

import exiftool

245

from exiftool.exceptions import (

246

ExifToolException,

247

ExifToolProcessStateError,

248

ExifToolExecuteException,

249

ExifToolExecuteError,

250

ExifToolVersionError

251

)

252

253

def safe_get_metadata(file_paths):

254

"""

255

Safely extract metadata with comprehensive error handling.

256

"""

257

try:

258

with exiftool.ExifToolHelper() as et:

259

return et.get_metadata(file_paths)

260

261

except ExifToolVersionError as e:

262

print(f"ExifTool version incompatible: {e}")

263

print("Please update to exiftool 12.15 or later")

264

return None

265

266

except ExifToolExecuteError as e:

267

print(f"Command execution failed:")

268

print(f" Exit status: {e.returncode}")

269

print(f" Command: {' '.join(e.cmd)}")

270

if e.stderr:

271

print(f" Error: {e.stderr}")

272

return None

273

274

except ExifToolProcessStateError as e:

275

print(f"Subprocess state error: {e}")

276

return None

277

278

except ExifToolException as e:

279

print(f"ExifTool library error: {e}")

280

return None

281

282

except Exception as e:

283

print(f"Unexpected error: {e}")

284

return None

285

286

# Usage

287

metadata = safe_get_metadata(['photo1.jpg', 'photo2.png'])

288

if metadata:

289

for data in metadata:

290

print(f"Successfully processed: {data['SourceFile']}")

291

```

292

293

### Error Information Extraction

294

295

```python

296

from exiftool.exceptions import ExifToolExecuteException

297

298

try:

299

with exiftool.ExifTool() as et:

300

et.execute('-invalid-option', 'file.jpg')

301

except ExifToolExecuteException as e:

302

# Access detailed error information

303

print(f"Command that failed: {' '.join(e.cmd)}")

304

print(f"Exit code: {e.returncode}")

305

print(f"Standard output: {e.stdout}")

306

print(f"Error output: {e.stderr}")

307

308

# Error information can be used for logging or debugging

309

error_details = {

310

'command': e.cmd,

311

'exit_code': e.returncode,

312

'stdout': e.stdout,

313

'stderr': e.stderr,

314

'error_type': type(e).__name__

315

}

316

print(f"Error details: {error_details}")

317

```