or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build-integration.mdbuiltin-methods.mdcore-operations.mddata-models.mdexceptions.mdindex.mdmethod-system.mdversioningit-class.md

exceptions.mddocs/

0

# Exception Handling

1

2

Comprehensive error hierarchy for handling configuration errors, VCS issues, method validation problems, and other exceptional conditions in versioningit operations.

3

4

## Capabilities

5

6

### Base Exception

7

8

Root exception class for all versioningit-specific errors.

9

10

```python { .api }

11

class Error(Exception):

12

"""Base class of all versioningit-specific errors."""

13

```

14

15

### Configuration Errors

16

17

Errors related to invalid configuration settings and values.

18

19

```python { .api }

20

class ConfigError(Error, ValueError):

21

"""

22

Raised when the versioningit configuration contains invalid settings.

23

24

This includes invalid parameter types, missing required fields,

25

invalid format strings, and other configuration validation failures.

26

"""

27

28

class NotVersioningitError(Error):

29

"""

30

Raised when versioningit is used on a project that does not have

31

versioningit enabled.

32

"""

33

34

class NoConfigFileError(NotVersioningitError):

35

"""

36

Raised when versioningit is used on a project that does not contain a

37

versioningit.toml or pyproject.toml file.

38

"""

39

40

def __init__(self, project_dir: Path) -> None:

41

self.project_dir: Path = project_dir

42

"""The path to the project directory."""

43

44

def __str__(self) -> str:

45

return f"No pyproject.toml or versioningit.toml file in {self.project_dir}"

46

47

class NoConfigSectionError(NotVersioningitError):

48

"""

49

Raised when versioningit is used on a project whose versioningit.toml or

50

pyproject.toml file does not contain a versioningit configuration table.

51

"""

52

53

def __init__(self, config_path: Path) -> None:

54

self.config_path: Path = config_path

55

"""The path to the configuration file."""

56

57

def __str__(self) -> str:

58

return f"versioningit not configured in {self.config_path}"

59

```

60

61

### Method Errors

62

63

Errors related to method loading, validation, and execution.

64

65

```python { .api }

66

class MethodError(Error):

67

"""

68

Raised when a method is invalid or returns an invalid value.

69

70

This includes entry points that don't resolve to callables,

71

methods that return wrong types, and method loading failures.

72

"""

73

```

74

75

### Version Control Errors

76

77

Errors related to VCS operations and repository state.

78

79

```python { .api }

80

class NotVCSError(Error):

81

"""

82

Raised when versioningit is run in a directory that is not under

83

version control or when the relevant VCS program is not installed.

84

"""

85

86

class NoTagError(Error):

87

"""

88

Raised when a tag cannot be found in version control.

89

90

This occurs when the repository has no tags or no tags match

91

the configured patterns.

92

"""

93

```

94

95

### Version Processing Errors

96

97

Errors related to tag and version string processing.

98

99

```python { .api }

100

class InvalidTagError(Error, ValueError):

101

"""

102

Raised by tag2version methods when passed a tag that they cannot work with.

103

104

This includes tags that don't match required patterns or contain

105

invalid version information.

106

"""

107

108

class InvalidVersionError(Error, ValueError):

109

"""

110

Raised by next-version and template-fields methods when passed a

111

version that they cannot work with.

112

113

This includes malformed version strings or versions that don't

114

conform to expected formats.

115

"""

116

```

117

118

### Source Distribution Errors

119

120

Errors related to PKG-INFO file handling and source distributions.

121

122

```python { .api }

123

class NotSdistError(Error):

124

"""

125

Raised when attempting to read a PKG-INFO file from a directory

126

that doesn't have one.

127

128

This typically occurs when fallback mode tries to read version

129

information from a source distribution but no PKG-INFO file exists.

130

"""

131

```

132

133

## Usage Examples

134

135

### Basic Error Handling

136

137

```python

138

from versioningit import get_version

139

from versioningit.errors import (

140

NotVCSError, NoConfigFileError, ConfigError,

141

MethodError, InvalidTagError

142

)

143

144

try:

145

version = get_version()

146

print(f"Version: {version}")

147

except NotVCSError:

148

print("Not in a version control repository")

149

except NoConfigFileError:

150

print("No configuration file found")

151

except ConfigError as e:

152

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

153

except MethodError as e:

154

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

155

except Exception as e:

156

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

157

```

158

159

### Handling Configuration Errors

160

161

```python

162

from versioningit import Versioningit

163

from versioningit.errors import ConfigError, NoConfigSectionError

164

165

config = {

166

"vcs": {"method": "git"},

167

"tag2version": {"method": "basic", "rmprefix": 123}, # Wrong type

168

"format": {"invalid-state": "template"} # Invalid state key

169

}

170

171

try:

172

vgit = Versioningit.from_project_dir(config=config)

173

except ConfigError as e:

174

print(f"Invalid configuration: {e}")

175

176

try:

177

vgit = Versioningit.from_project_dir("/path/without/config")

178

except NoConfigSectionError as e:

179

print(f"No versioningit configuration: {e}")

180

print(f"Config file: {e.config_path}")

181

```

182

183

### VCS Error Handling

184

185

```python

186

from versioningit import get_version, get_next_version

187

from versioningit.errors import NotVCSError, NoTagError

188

189

try:

190

version = get_version(fallback=False)

191

except NotVCSError:

192

print("Project must be under version control")

193

194

try:

195

next_version = get_next_version()

196

except NoTagError:

197

print("No tags found in repository")

198

except NotVCSError:

199

print("Not a version control repository")

200

```

201

202

### Method Error Handling

203

204

```python

205

from versioningit.methods import EntryPointSpec, CustomMethodSpec

206

from versioningit.errors import MethodError, ConfigError

207

208

# Entry point not found

209

try:

210

spec = EntryPointSpec(group="versioningit.tag2version", name="nonexistent")

211

method = spec.load(".")

212

except ConfigError as e:

213

print(f"Entry point error: {e}")

214

215

# Custom method not callable

216

try:

217

spec = CustomMethodSpec(

218

module="sys", # sys.path is not callable

219

value="path",

220

module_dir=None

221

)

222

method = spec.load(".")

223

except MethodError as e:

224

print(f"Method not callable: {e}")

225

```

226

227

### Version Processing Errors

228

229

```python

230

from versioningit.basics import basic_tag2version

231

from versioningit.next_version import next_minor_version

232

from versioningit.errors import InvalidTagError, InvalidVersionError

233

234

# Invalid tag

235

try:

236

version = basic_tag2version(

237

tag="not-a-version-tag",

238

params={"regex": r"v(?P<version>\d+\.\d+\.\d+)", "require-match": True}

239

)

240

except InvalidTagError as e:

241

print(f"Tag doesn't match pattern: {e}")

242

243

# Invalid version

244

try:

245

next_ver = next_minor_version(

246

version="not.a.valid.version.string",

247

branch=None,

248

params={}

249

)

250

except InvalidVersionError as e:

251

print(f"Cannot parse version: {e}")

252

```

253

254

### Fallback and Recovery

255

256

```python

257

from versioningit import get_version

258

from versioningit.errors import NotVCSError, NotSdistError

259

260

def get_version_with_fallback(project_dir="."):

261

"""Get version with multiple fallback strategies."""

262

263

# Try VCS first

264

try:

265

return get_version(project_dir, fallback=False)

266

except NotVCSError:

267

pass

268

269

# Try PKG-INFO fallback

270

try:

271

return get_version(project_dir, fallback=True)

272

except NotSdistError:

273

pass

274

275

# Try with default version

276

try:

277

config = {"default-version": "0.0.0.dev0"}

278

return get_version(project_dir, config=config)

279

except Exception:

280

pass

281

282

# Final fallback

283

return "unknown"

284

285

version = get_version_with_fallback()

286

print(f"Version: {version}")

287

```

288

289

### Error Context and Debugging

290

291

```python

292

from versioningit import Versioningit

293

from versioningit.errors import Error

294

import logging

295

296

# Enable debug logging

297

logging.basicConfig(level=logging.DEBUG)

298

299

try:

300

vgit = Versioningit.from_project_dir()

301

report = vgit.run()

302

303

if report.using_default_version:

304

print("Warning: Used default version due to errors")

305

306

print(f"Version: {report.version}")

307

308

except Error as e:

309

print(f"Versioningit error: {type(e).__name__}: {e}")

310

# Debug info available in logs

311

except Exception as e:

312

print(f"Unexpected error: {type(e).__name__}: {e}")

313

raise

314

```

315

316

### Custom Error Handling in Methods

317

318

```python

319

from versioningit.errors import ConfigError, InvalidTagError, MethodError

320

321

def custom_tag2version_method(*, tag: str, params: dict) -> str:

322

"""Custom method with proper error handling."""

323

324

# Validate parameters

325

required_prefix = params.get("required-prefix")

326

if required_prefix and not isinstance(required_prefix, str):

327

raise ConfigError("required-prefix must be a string")

328

329

# Validate tag format

330

if required_prefix and not tag.startswith(required_prefix):

331

raise InvalidTagError(f"Tag {tag!r} must start with {required_prefix!r}")

332

333

# Process tag

334

try:

335

if required_prefix:

336

tag = tag[len(required_prefix):]

337

return tag.lstrip("v")

338

except Exception as e:

339

raise MethodError(f"Failed to process tag {tag!r}: {e}")

340

341

def custom_vcs_method(*, project_dir: Path, params: dict) -> VCSDescription:

342

"""Custom VCS method with error handling."""

343

344

try:

345

# Custom VCS operations

346

result = run_custom_vcs_command(project_dir)

347

return VCSDescription(

348

tag=result["tag"],

349

state=result["state"],

350

branch=result["branch"],

351

fields=result["fields"]

352

)

353

except subprocess.CalledProcessError as e:

354

raise NotVCSError(f"VCS command failed: {e}")

355

except KeyError as e:

356

raise MethodError(f"Missing required VCS result field: {e}")

357

```

358

359

### Exception Hierarchy

360

361

```python

362

# All versioningit exceptions inherit from Error

363

from versioningit.errors import *

364

365

def handle_versioningit_error(e: Exception):

366

"""Handle different types of versioningit errors."""

367

368

if isinstance(e, NotVersioningitError):

369

if isinstance(e, NoConfigFileError):

370

print(f"Missing config file in {e.project_dir}")

371

elif isinstance(e, NoConfigSectionError):

372

print(f"No versioningit config in {e.config_path}")

373

else:

374

print("Project doesn't use versioningit")

375

376

elif isinstance(e, ConfigError):

377

print(f"Configuration problem: {e}")

378

379

elif isinstance(e, MethodError):

380

print(f"Method problem: {e}")

381

382

elif isinstance(e, NotVCSError):

383

print("Not under version control")

384

385

elif isinstance(e, NoTagError):

386

print("No version tags found")

387

388

elif isinstance(e, InvalidTagError):

389

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

390

391

elif isinstance(e, InvalidVersionError):

392

print(f"Invalid version format: {e}")

393

394

elif isinstance(e, NotSdistError):

395

print("No PKG-INFO file found for fallback")

396

397

elif isinstance(e, Error):

398

print(f"Other versioningit error: {e}")

399

400

else:

401

print(f"Non-versioningit error: {e}")

402

```