or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdconfiguration.mderror-handling.mdindex.mdtask-composition.mdtask-execution.mdvariables.md

error-handling.mddocs/

0

# Error Handling

1

2

Comprehensive exception hierarchy for handling various error conditions with specific exit codes and descriptive error messages.

3

4

## Capabilities

5

6

### Base Exception Class

7

8

Root exception class for all taskipy-specific errors.

9

10

```python { .api }

11

class TaskipyError(Exception):

12

"""Base exception class for all taskipy errors."""

13

exit_code = 1

14

```

15

16

### Configuration Errors

17

18

Errors related to pyproject.toml file handling and parsing.

19

20

```python { .api }

21

class MissingPyProjectFileError(TaskipyError):

22

"""Raised when no pyproject.toml file is found in directory or parent directories."""

23

24

class MalformedPyProjectError(TaskipyError):

25

"""Raised when pyproject.toml file is malformed and cannot be parsed."""

26

def __init__(self, reason: Optional[str] = None):

27

"""

28

Initialize with optional reason for malformation.

29

30

Args:

31

reason: Specific reason for TOML parsing failure

32

"""

33

34

class MissingTaskipyTasksSectionError(TaskipyError):

35

"""Raised when [tool.taskipy.tasks] section is missing from pyproject.toml."""

36

exit_code = 127

37

38

class MissingTaskipySettingsSectionError(TaskipyError):

39

"""Raised when [tool.taskipy.settings] section is expected but missing."""

40

exit_code = 127

41

42

class EmptyTasksSectionError(TaskipyError):

43

"""Raised when tasks section exists but contains no tasks."""

44

exit_code = 127

45

```

46

47

### Task Execution Errors

48

49

Errors that occur during task discovery and execution.

50

51

```python { .api }

52

class TaskNotFoundError(TaskipyError):

53

"""Raised when a requested task cannot be found."""

54

exit_code = 127

55

56

def __init__(self, task_name: str, suggestion: Optional[str] = None):

57

"""

58

Initialize with task name and optional suggestion.

59

60

Args:

61

task_name: Name of the task that was not found

62

suggestion: Suggested similar task name (from difflib)

63

"""

64

65

class MalformedTaskError(TaskipyError):

66

"""Raised when a task definition is invalid or malformed."""

67

68

def __init__(self, task_name: str, reason: str):

69

"""

70

Initialize with task name and specific reason.

71

72

Args:

73

task_name: Name of the malformed task

74

reason: Specific reason for the malformation

75

"""

76

```

77

78

### Variable and Settings Errors

79

80

Errors related to variable substitution and settings configuration.

81

82

```python { .api }

83

class CircularVariableError(TaskipyError):

84

"""Raised when circular dependencies are detected in recursive variables."""

85

exit_code = 127

86

87

class InvalidVariableError(TaskipyError):

88

"""Raised when a variable definition is invalid."""

89

exit_code = 127

90

91

def __init__(self, variable: str, reason: str):

92

"""

93

Initialize with variable name and reason.

94

95

Args:

96

variable: Name of the invalid variable

97

reason: Specific reason for invalidity

98

"""

99

100

class InvalidRunnerTypeError(TaskipyError):

101

"""Raised when runner setting is not a string."""

102

```

103

104

### Usage Errors

105

106

Errors related to command-line usage and argument parsing.

107

108

```python { .api }

109

class InvalidUsageError(TaskipyError):

110

"""Raised when command-line arguments are invalid."""

111

exit_code = 127

112

113

def __init__(self, parser: ArgumentParser):

114

"""

115

Initialize with argument parser for usage message.

116

117

Args:

118

parser: ArgumentParser instance for generating usage help

119

"""

120

```

121

122

## Usage Examples

123

124

### Basic Error Handling

125

126

```python

127

from taskipy.cli import run

128

from taskipy.exceptions import TaskipyError, TaskNotFoundError

129

130

try:

131

exit_code = run(['nonexistent_task'])

132

except TaskNotFoundError as e:

133

print(f"Task not found: {e}")

134

if e.suggestion:

135

print(f"Did you mean: {e.suggestion}")

136

exit_code = e.exit_code

137

except TaskipyError as e:

138

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

139

exit_code = e.exit_code

140

```

141

142

### Configuration Error Handling

143

144

```python

145

from taskipy.pyproject import PyProject

146

from taskipy.exceptions import (

147

MissingPyProjectFileError,

148

MalformedPyProjectError,

149

MissingTaskipyTasksSectionError

150

)

151

from pathlib import Path

152

153

try:

154

project = PyProject(Path('/path/to/project'))

155

tasks = project.tasks

156

except MissingPyProjectFileError:

157

print("Error: No pyproject.toml file found")

158

print("Make sure you're in a directory with a pyproject.toml file")

159

except MalformedPyProjectError as e:

160

print(f"Error: Invalid pyproject.toml syntax")

161

if e.reason:

162

print(f"Reason: {e.reason}")

163

except MissingTaskipyTasksSectionError:

164

print("Error: No [tool.taskipy.tasks] section found")

165

print("Add tasks to your pyproject.toml file")

166

```

167

168

### Variable Error Handling

169

170

```python

171

from taskipy.task_runner import TaskRunner

172

from taskipy.exceptions import CircularVariableError, InvalidVariableError, MalformedTaskError

173

from pathlib import Path

174

175

try:

176

runner = TaskRunner(Path('.'))

177

exit_code = runner.run('my_task', [])

178

except CircularVariableError:

179

print("Error: Circular dependency detected in variables")

180

print("Check your [tool.taskipy.variables] for circular references")

181

except InvalidVariableError as e:

182

print(f"Error: Invalid variable '{e.variable}'")

183

print(f"Reason: {e.reason}")

184

except MalformedTaskError as e:

185

print(f"Error: Task '{e.task}' is malformed")

186

print(f"Reason: {e.reason}")

187

```

188

189

### Complete Error Handling Pattern

190

191

```python

192

from taskipy.cli import run

193

from taskipy.exceptions import *

194

import sys

195

196

def safe_task_runner(task_name, args=None):

197

"""Safely run a task with comprehensive error handling."""

198

if args is None:

199

args = []

200

201

try:

202

return run([task_name] + args)

203

204

except TaskNotFoundError as e:

205

print(f"❌ Task '{e.task}' not found", file=sys.stderr)

206

if e.suggestion:

207

print(f"πŸ’‘ Did you mean '{e.suggestion}'?", file=sys.stderr)

208

return e.exit_code

209

210

except MissingPyProjectFileError:

211

print("❌ No pyproject.toml file found", file=sys.stderr)

212

print("πŸ’‘ Make sure you're in a Python project directory", file=sys.stderr)

213

return 1

214

215

except MalformedPyProjectError as e:

216

print("❌ Invalid pyproject.toml syntax", file=sys.stderr)

217

if e.reason:

218

print(f"πŸ“ {e.reason}", file=sys.stderr)

219

return 1

220

221

except MissingTaskipyTasksSectionError:

222

print("❌ No tasks defined", file=sys.stderr)

223

print("πŸ’‘ Add [tool.taskipy.tasks] section to pyproject.toml", file=sys.stderr)

224

return 127

225

226

except CircularVariableError:

227

print("❌ Circular variable dependency detected", file=sys.stderr)

228

print("πŸ’‘ Check [tool.taskipy.variables] for circular references", file=sys.stderr)

229

return 127

230

231

except InvalidVariableError as e:

232

print(f"❌ Invalid variable '{e.variable}': {e.reason}", file=sys.stderr)

233

return 127

234

235

except MalformedTaskError as e:

236

print(f"❌ Task '{e.task}' is malformed: {e.reason}", file=sys.stderr)

237

return 1

238

239

except InvalidRunnerTypeError:

240

print("❌ Runner setting must be a string", file=sys.stderr)

241

print("πŸ’‘ Check [tool.taskipy.settings.runner] in pyproject.toml", file=sys.stderr)

242

return 1

243

244

except TaskipyError as e:

245

print(f"❌ Taskipy error: {e}", file=sys.stderr)

246

return e.exit_code

247

248

except Exception as e:

249

print(f"❌ Unexpected error: {e}", file=sys.stderr)

250

return 1

251

252

# Usage

253

if __name__ == "__main__":

254

exit_code = safe_task_runner('test', ['--verbose'])

255

sys.exit(exit_code)

256

```

257

258

## Exit Codes

259

260

Taskipy uses specific exit codes to indicate different types of failures:

261

262

- **0**: Success

263

- **1**: General error (TaskipyError, configuration issues)

264

- **127**: Command not found or invalid usage (TaskNotFoundError, InvalidUsageError, missing sections)

265

266

### Exit Code Usage

267

268

```python

269

import subprocess

270

import sys

271

272

# Running taskipy as subprocess

273

result = subprocess.run(['task', 'test'], capture_output=True)

274

275

if result.returncode == 0:

276

print("βœ… Task completed successfully")

277

elif result.returncode == 127:

278

print("❌ Task not found or invalid usage")

279

print("Check task name and available tasks with 'task --list'")

280

else:

281

print(f"❌ Task failed with exit code {result.returncode}")

282

print("Check task output for details")

283

```

284

285

## Error Messages

286

287

### Task Not Found

288

289

```

290

could not find task "tets", did you mean "test"?

291

```

292

293

### Missing Configuration

294

295

```

296

no pyproject.toml file found in this directory or parent directories

297

```

298

299

### Malformed Configuration

300

301

```

302

pyproject.toml file is malformed and could not be read. reason: Invalid TOML syntax

303

```

304

305

### Variable Errors

306

307

```

308

variable src_path is invalid. reason: expected variable to contain a string or be a table with a key "var"

309

```

310

311

```

312

cannot resolve variables, found variables that depend on each other.

313

```

314

315

### Task Errors

316

317

```

318

the task "test" in the pyproject.toml file is malformed. reason: tasks must be strings, or dicts that contain { cmd, cwd, help, use_vars }

319

```

320

321

## Debugging Tips

322

323

### Enable Verbose Error Reporting

324

325

```python

326

import logging

327

logging.basicConfig(level=logging.DEBUG)

328

329

# Now taskipy operations will show more detailed information

330

```

331

332

### Common Error Scenarios

333

334

1. **Typo in Task Name**: Use `task --list` to see available tasks

335

2. **Missing pyproject.toml**: Ensure you're in the correct directory

336

3. **TOML Syntax Error**: Validate TOML syntax using online validators

337

4. **Circular Variables**: Draw variable dependency graph to identify cycles

338

5. **Missing Variable**: Check variable names match exactly (case-sensitive)

339

340

### Error Prevention

341

342

```toml

343

# Use descriptive task names to avoid typos

344

[tool.taskipy.tasks]

345

run_tests = "pytest" # Clear and descriptive

346

test = "pytest" # Short but clear

347

348

# Validate variable references

349

[tool.taskipy.variables]

350

src_dir = "src"

351

# Make sure variables exist before referencing them

352

package_dir = { var = "{src_dir}/mypackage", recursive = true }

353

```