or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

actions.mdcli.mdcore-api.mdexceptions.mdindex.mdtask-definition.mdtools.md

exceptions.mddocs/

0

# Exceptions

1

2

Comprehensive exception hierarchy for task failures, configuration errors, execution problems, and user input validation with detailed error reporting.

3

4

## Capabilities

5

6

### User Input and Configuration Errors

7

8

Exceptions raised for invalid user input, command line arguments, and configuration problems.

9

10

```python { .api }

11

class InvalidCommand(Exception):

12

"""

13

Invalid command line argument or command usage.

14

15

Raised when user provides invalid command line arguments, unknown commands,

16

or invalid task/target names. Provides contextual error messages.

17

"""

18

19

def __init__(self, *args, **kwargs):

20

"""

21

Initialize command error.

22

23

Args:

24

*args: Standard exception arguments

25

not_found (str, optional): Name of command/task/target not found

26

"""

27

self.not_found = kwargs.pop('not_found', None)

28

self.cmd_used = None # Set by CLI when command is known

29

self.bin_name = 'doit' # Binary name for error messages

30

31

def __str__(self):

32

"""Return formatted error message with usage hints"""

33

```

34

35

```python { .api }

36

class InvalidDodoFile(Exception):

37

"""

38

Invalid dodo file or dodo file loading error.

39

40

Raised when dodo file cannot be found, imported, or contains invalid

41

configuration or task definitions.

42

"""

43

```

44

45

```python { .api }

46

class InvalidTask(Exception):

47

"""

48

Invalid task instance or task definition.

49

50

Raised when task definition contains invalid attributes, missing required

51

fields, or violates task specification rules.

52

"""

53

```

54

55

### Task Execution Failures

56

57

Exception hierarchy for different types of task execution problems and failures.

58

59

```python { .api }

60

class BaseFail(CatchedException):

61

"""

62

Base class for task failures and errors.

63

64

Contains information about task failures including exception details,

65

traceback information, and reporting flags. Used to save failure info

66

and might contain a caught Exception.

67

"""

68

```

69

70

```python { .api }

71

class TaskFailed(BaseFail):

72

"""

73

Task execution was not successful.

74

75

Raised when a task's action execution fails (non-zero exit code for shell

76

commands, raised exception for Python actions, etc.). Indicates the task

77

itself failed, not an error in doit's execution.

78

"""

79

```

80

81

```python { .api }

82

class TaskError(BaseFail):

83

"""

84

Error while trying to execute task.

85

86

Raised when there's an error in doit's task execution machinery rather

87

than in the task action itself. Examples: missing dependencies,

88

action setup failures, internal doit errors.

89

"""

90

```

91

92

```python { .api }

93

class UnmetDependency(TaskError):

94

"""

95

Task was not executed because a dependent task failed or is ignored.

96

97

Raised when task cannot run due to dependency failures. Prevents execution

98

cascade when prerequisite tasks fail or are explicitly ignored.

99

"""

100

```

101

102

```python { .api }

103

class SetupError(TaskError):

104

"""

105

Error while trying to execute setup object.

106

107

Raised when task setup actions (executed before main actions) fail

108

or cannot be properly initialized and executed.

109

"""

110

```

111

112

```python { .api }

113

class DependencyError(TaskError):

114

"""

115

Error while checking if task is up-to-date or saving task status.

116

117

Raised when dependency checking fails due to file system errors,

118

database problems, or issues with uptodate checkers.

119

"""

120

```

121

122

### Legacy Exception Support

123

124

Deprecated exception classes maintained for backward compatibility.

125

126

```python { .api }

127

class CatchedException:

128

"""

129

DEPRECATED: Use BaseFail instead (deprecated 2022-04-22, 0.36.0 release).

130

131

Legacy base class for caught exceptions. Contains poor grammar and

132

doesn't handle all BaseFail cases properly. Maintained for compatibility.

133

"""

134

135

def __init__(self, msg, exception=None, report=True):

136

"""

137

Initialize caught exception.

138

139

Args:

140

msg (str): Error message

141

exception (Exception, optional): Original exception

142

report (bool): Whether failure should be reported

143

"""

144

self.message = msg

145

self.traceback = ''

146

self.report = report

147

148

def get_msg(self):

149

"""Return full exception description including traceback"""

150

151

def get_name(self):

152

"""Get failure kind name"""

153

154

def __str__(self):

155

"""Return formatted exception string"""

156

```

157

158

### Usage Examples

159

160

#### Command Line Error Handling

161

162

```python

163

from doit.exceptions import InvalidCommand

164

165

def validate_task_name(task_name, available_tasks):

166

"""Validate that task name exists"""

167

if task_name not in available_tasks:

168

raise InvalidCommand(

169

f"Task '{task_name}' not found",

170

not_found=task_name

171

)

172

173

# Error message will include helpful suggestions:

174

# "Invalid parameter: 'nonexistent'. Must be a command, task, or a target.

175

# Type 'doit help' to see available commands.

176

# Type 'doit list' to see available tasks."

177

```

178

179

#### Task Definition Validation

180

181

```python

182

from doit.exceptions import InvalidTask

183

184

def validate_task_definition(task_dict):

185

"""Validate task definition dictionary"""

186

if 'actions' not in task_dict and 'task_dep' not in task_dict:

187

raise InvalidTask(

188

"Task must contain either 'actions' or 'task_dep'"

189

)

190

191

if 'name' in task_dict and task_dict['name'].startswith('_'):

192

raise InvalidTask(

193

"Task names cannot start with underscore"

194

)

195

196

def task_invalid_example():

197

"""This will raise InvalidTask"""

198

return {

199

'name': '_private', # Invalid name

200

# Missing actions or task_dep

201

}

202

```

203

204

#### Action Failure Handling

205

206

```python

207

from doit.exceptions import TaskFailed, TaskError

208

209

def failing_action():

210

"""Action that might fail"""

211

import random

212

213

if random.random() < 0.5:

214

# Task logic failure

215

raise TaskFailed("Business logic failed")

216

else:

217

# System/infrastructure error

218

raise TaskError("Database connection failed")

219

220

def task_with_error_handling():

221

"""Task with custom error handling"""

222

def safe_action():

223

try:

224

# Some risky operation

225

result = risky_operation()

226

return result

227

except ValueError as e:

228

# Convert to doit exception

229

raise TaskFailed(f"Invalid input data: {e}")

230

except ConnectionError as e:

231

# Infrastructure error

232

raise TaskError(f"Service unavailable: {e}")

233

234

return {

235

'actions': [safe_action],

236

'verbosity': 2

237

}

238

```

239

240

#### Dependency Error Scenarios

241

242

```python

243

from doit.exceptions import UnmetDependency, DependencyError

244

245

def task_primary():

246

"""Primary task that might fail"""

247

return {

248

'actions': ['exit 1'], # Will fail

249

}

250

251

def task_dependent():

252

"""Task that depends on primary"""

253

return {

254

'actions': ['echo "This will not run"'],

255

'task_dep': ['primary'] # UnmetDependency if primary fails

256

}

257

258

def check_file_dependency():

259

"""Custom uptodate checker that might error"""

260

try:

261

import os

262

return os.path.exists('required_file.txt')

263

except PermissionError:

264

# File system access error

265

raise DependencyError("Cannot access dependency file")

266

267

def task_with_dep_check():

268

return {

269

'actions': ['echo "Running with dependency check"'],

270

'uptodate': [check_file_dependency]

271

}

272

```

273

274

#### Exception Information Access

275

276

```python

277

from doit.exceptions import BaseFail

278

279

def handle_task_failure(exception):

280

"""Handle task failure with detailed information"""

281

if isinstance(exception, BaseFail):

282

print(f"Failure type: {exception.get_name()}")

283

print(f"Message: {exception.message}")

284

285

if exception.traceback:

286

print("Traceback:")

287

print(''.join(exception.traceback))

288

289

if not exception.report:

290

print("(This failure was marked as non-reportable)")

291

292

return exception.get_msg() # Full description

293

```