or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

exceptions.mdindex.mdlockfile.mdpipfile.mdrequirement.md

exceptions.mddocs/

0

# Exception Handling

1

2

RequirementsLib provides comprehensive exception classes for handling various error conditions during requirement parsing, file operations, and format conversions. These exceptions enable proper error handling and debugging in applications using the library.

3

4

## Capabilities

5

6

### Base Exceptions

7

8

Core exception classes that serve as the foundation for more specific error types.

9

10

```python { .api }

11

class RequirementError(Exception):

12

"""

13

Base exception for requirement-related errors.

14

15

Raised when parsing or processing requirements fails due to

16

malformed input, invalid specifications, or processing errors.

17

"""

18

```

19

20

### Parameter Validation Exceptions

21

22

Handle missing or invalid parameters during requirement processing.

23

24

```python { .api }

25

class MissingParameter(Exception):

26

"""

27

Raised when required parameters are missing.

28

29

Provides methods for generating and displaying helpful error messages

30

to assist with debugging parameter-related issues.

31

"""

32

33

def __init__(self, param):

34

"""

35

Initialize with missing parameter name.

36

37

Parameters:

38

- param: Name of the missing parameter

39

"""

40

41

@classmethod

42

def get_message(cls, param):

43

"""

44

Generate error message for missing parameter.

45

46

Parameters:

47

- param: Parameter name

48

49

Returns:

50

str: Formatted error message

51

"""

52

53

def show(self, param):

54

"""

55

Display error message to stderr.

56

57

Parameters:

58

- param: Parameter name

59

"""

60

```

61

62

### File Corruption Exceptions

63

64

Handle various types of file corruption and parsing errors.

65

66

```python { .api }

67

class FileCorruptException(OSError):

68

"""

69

Base exception for corrupt file errors.

70

71

Extends OSError to provide file-specific error handling with

72

support for backup file paths and detailed error messages.

73

"""

74

75

def __init__(self, path, *args, backup_path=None):

76

"""

77

Initialize with file path and optional backup path.

78

79

Parameters:

80

- path: Path to the corrupt file

81

- backup_path: Optional path to backup file

82

"""

83

84

def get_message(self, path, backup_path=None):

85

"""

86

Generate error message for file corruption.

87

88

Parameters:

89

- path: Path to corrupt file

90

- backup_path: Optional backup file path

91

92

Returns:

93

str: Formatted error message

94

"""

95

96

def show(self):

97

"""Display error message to user."""

98

```

99

100

### Lockfile-Specific Exceptions

101

102

Handle errors specific to Pipfile.lock operations.

103

104

```python { .api }

105

class LockfileCorruptException(FileCorruptException):

106

"""

107

Raised when lockfile is corrupt or unreadable.

108

109

Occurs when Pipfile.lock files have invalid JSON, missing required

110

sections, or other structural problems that prevent parsing.

111

"""

112

113

def __init__(self, path, backup_path=None):

114

"""

115

Initialize with lockfile path.

116

117

Parameters:

118

- path: Path to corrupt lockfile

119

- backup_path: Optional backup file path

120

"""

121

122

def get_message(self, path, backup_path=None):

123

"""

124

Generate lockfile-specific error message.

125

126

Parameters:

127

- path: Path to corrupt lockfile

128

- backup_path: Optional backup file path

129

130

Returns:

131

str: Formatted error message

132

"""

133

134

def show(self, path, backup_path=None):

135

"""

136

Display lockfile error message.

137

138

Parameters:

139

- path: Path to corrupt lockfile

140

- backup_path: Optional backup file path

141

"""

142

```

143

144

### Pipfile-Specific Exceptions

145

146

Handle errors specific to Pipfile operations.

147

148

```python { .api }

149

class PipfileCorruptException(FileCorruptException):

150

"""

151

Raised when Pipfile is corrupt or unreadable.

152

153

Occurs when Pipfile has invalid TOML syntax, missing required

154

sections, or other structural problems that prevent parsing.

155

"""

156

157

def __init__(self, path, backup_path=None):

158

"""

159

Initialize with Pipfile path.

160

161

Parameters:

162

- path: Path to corrupt Pipfile

163

- backup_path: Optional backup file path

164

"""

165

166

def get_message(self, path, backup_path=None):

167

"""

168

Generate Pipfile-specific error message.

169

170

Parameters:

171

- path: Path to corrupt Pipfile

172

- backup_path: Optional backup file path

173

174

Returns:

175

str: Formatted error message

176

"""

177

178

def show(self, path, backup_path=None):

179

"""

180

Display Pipfile error message.

181

182

Parameters:

183

- path: Path to corrupt Pipfile

184

- backup_path: Optional backup file path

185

"""

186

```

187

188

### File Not Found Exceptions

189

190

Handle missing file errors.

191

192

```python { .api }

193

class PipfileNotFound(FileNotFoundError):

194

"""

195

Raised when Pipfile cannot be found.

196

197

Extends FileNotFoundError to provide Pipfile-specific context

198

when attempting to load Pipfiles that don't exist.

199

"""

200

201

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

202

"""

203

Initialize with Pipfile path.

204

205

Parameters:

206

- path: Path to missing Pipfile

207

"""

208

```

209

210

## Usage Examples

211

212

### Basic Exception Handling

213

214

```python

215

from requirementslib import Requirement, Pipfile, Lockfile

216

from requirementslib.exceptions import (

217

RequirementError,

218

MissingParameter,

219

LockfileCorruptException,

220

PipfileCorruptException,

221

PipfileNotFound

222

)

223

224

# Handle requirement parsing errors

225

try:

226

req = Requirement.from_line("invalid requirement line")

227

except RequirementError as e:

228

print(f"Failed to parse requirement: {e}")

229

230

# Handle missing parameter errors

231

try:

232

# Some operation that might have missing parameters

233

pass

234

except MissingParameter as e:

235

print(f"Missing required parameter: {e}")

236

e.show(e.args[0]) # Show detailed error message

237

```

238

239

### File Operation Error Handling

240

241

```python

242

from requirementslib import Pipfile, Lockfile

243

from requirementslib.exceptions import (

244

PipfileNotFound,

245

PipfileCorruptException,

246

LockfileCorruptException

247

)

248

249

# Handle Pipfile loading errors

250

try:

251

pipfile = Pipfile.load("./Pipfile")

252

except PipfileNotFound as e:

253

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

254

# Create new Pipfile or use defaults

255

pipfile = Pipfile.load("./Pipfile", create=True)

256

except PipfileCorruptException as e:

257

print(f"Pipfile is corrupt: {e}")

258

e.show(e.args[0]) # Show detailed error message

259

260

# Handle lockfile loading errors

261

try:

262

lockfile = Lockfile.load("./Pipfile.lock")

263

except LockfileCorruptException as e:

264

print(f"Lockfile is corrupt: {e}")

265

e.show(e.args[0], e.args[1] if len(e.args) > 1 else None)

266

# Regenerate lockfile from Pipfile

267

lockfile = Lockfile.lockfile_from_pipfile("./Pipfile")

268

```

269

270

### Comprehensive Error Handling

271

272

```python

273

from requirementslib import Requirement, Pipfile, Lockfile

274

from requirementslib.exceptions import *

275

import sys

276

277

def safe_parse_requirement(line):

278

"""Safely parse a requirement line with error handling."""

279

try:

280

return Requirement.from_line(line)

281

except RequirementError as e:

282

print(f"Error parsing requirement '{line}': {e}", file=sys.stderr)

283

return None

284

except MissingParameter as e:

285

print(f"Missing parameter while parsing '{line}':", file=sys.stderr)

286

e.show(e.args[0])

287

return None

288

289

def safe_load_pipfile(path):

290

"""Safely load a Pipfile with comprehensive error handling."""

291

try:

292

return Pipfile.load(path)

293

except PipfileNotFound:

294

print(f"Pipfile not found at {path}, creating new one")

295

return Pipfile.load(path, create=True)

296

except PipfileCorruptException as e:

297

print(f"Pipfile at {path} is corrupt:")

298

e.show(path)

299

return None

300

except Exception as e:

301

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

302

return None

303

304

def safe_load_lockfile(path, pipfile_path=None):

305

"""Safely load a lockfile with fallback to regeneration."""

306

try:

307

return Lockfile.load(path)

308

except LockfileCorruptException as e:

309

print(f"Lockfile at {path} is corrupt:")

310

e.show(path)

311

if pipfile_path:

312

print("Attempting to regenerate from Pipfile...")

313

try:

314

return Lockfile.lockfile_from_pipfile(pipfile_path)

315

except Exception as regen_error:

316

print(f"Failed to regenerate lockfile: {regen_error}")

317

return None

318

except Exception as e:

319

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

320

return None

321

322

# Example usage

323

requirements_lines = [

324

"requests>=2.25.0",

325

"invalid_requirement_line",

326

"django[redis]==3.2.0"

327

]

328

329

for line in requirements_lines:

330

req = safe_parse_requirement(line)

331

if req:

332

print(f"Successfully parsed: {req.name} {req.specifiers}")

333

334

pipfile = safe_load_pipfile("./Pipfile")

335

if pipfile:

336

lockfile = safe_load_lockfile("./Pipfile.lock", "./Pipfile")

337

```

338

339

### Custom Exception Handling

340

341

```python

342

from requirementslib.exceptions import RequirementError

343

import logging

344

345

# Set up logging for better error tracking

346

logging.basicConfig(level=logging.INFO)

347

logger = logging.getLogger(__name__)

348

349

def process_requirements_with_logging(requirements_lines):

350

"""Process requirements with detailed logging."""

351

successful = []

352

failed = []

353

354

for line in requirements_lines:

355

try:

356

req = Requirement.from_line(line)

357

successful.append(req)

358

logger.info(f"Successfully parsed: {req.name}")

359

except RequirementError as e:

360

failed.append((line, str(e)))

361

logger.error(f"Failed to parse '{line}': {e}")

362

except Exception as e:

363

failed.append((line, f"Unexpected error: {str(e)}"))

364

logger.error(f"Unexpected error parsing '{line}': {e}")

365

366

logger.info(f"Processed {len(successful)} requirements successfully")

367

logger.info(f"Failed to process {len(failed)} requirements")

368

369

return successful, failed

370

```