or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

change-management.mdcode-assistance.mderror-handling.mdindex.mdproject-management.mdrefactoring-operations.md

error-handling.mddocs/

0

# Error Handling

1

2

Exception hierarchy for handling various error conditions during code analysis and refactoring operations. Rope provides specific exception types for different failure scenarios to enable appropriate error handling and user feedback.

3

4

## Exception Hierarchy

5

6

All rope exceptions inherit from the base `RopeError` class, providing a consistent error handling interface.

7

8

```python { .api }

9

class RopeError(Exception):

10

"""

11

Base exception class for all rope errors.

12

All rope-specific exceptions inherit from this class.

13

"""

14

pass

15

```

16

17

## Capabilities

18

19

### Refactoring Errors

20

21

Errors that occur during refactoring operations due to code structure or safety constraints.

22

23

```python { .api }

24

class RefactoringError(RopeError):

25

"""

26

General refactoring error for operations that cannot be completed safely.

27

Raised when a refactoring violates safety constraints or encounters

28

unsupported code patterns.

29

"""

30

pass

31

32

class InterruptedTaskError(RopeError):

33

"""

34

Raised when a refactoring task is cancelled or interrupted.

35

Can occur when using TaskHandle to monitor long-running operations.

36

"""

37

pass

38

```

39

40

### Resource Errors

41

42

Errors related to file system operations and resource management.

43

44

```python { .api }

45

class ResourceNotFoundError(RopeError):

46

"""

47

Raised when attempting to access a resource that doesn't exist.

48

Common when using project.get_resource() with invalid paths.

49

"""

50

pass

51

```

52

53

### Module and Import Errors

54

55

Errors related to Python module loading and import resolution.

56

57

```python { .api }

58

class ModuleNotFoundError(RopeError):

59

"""

60

Raised when a Python module cannot be found or loaded.

61

Occurs during module resolution in project.get_module() operations.

62

"""

63

pass

64

65

class AttributeNotFoundError(RopeError):

66

"""

67

Raised when attempting to access a non-existent attribute.

68

Can occur during code analysis and refactoring operations.

69

"""

70

pass

71

72

class NameNotFoundError(RopeError):

73

"""

74

Raised when name resolution fails during code analysis.

75

Indicates that a referenced identifier cannot be resolved.

76

"""

77

pass

78

```

79

80

### Syntax and Validation Errors

81

82

Errors related to code syntax and identifier validation.

83

84

```python { .api }

85

class BadIdentifierError(RopeError):

86

"""

87

Raised when an invalid identifier is provided for refactoring.

88

Common in rename operations with non-Python identifiers.

89

"""

90

pass

91

92

class ModuleSyntaxError(RopeError):

93

"""

94

Raised when a Python module contains syntax errors.

95

Can occur during parsing and analysis operations.

96

"""

97

pass

98

99

class ModuleDecodeError(RopeError):

100

"""

101

Raised when a Python file cannot be decoded due to encoding issues.

102

Occurs when reading files with invalid or unsupported encodings.

103

"""

104

pass

105

```

106

107

### History and State Errors

108

109

Errors related to project history and state management.

110

111

```python { .api }

112

class HistoryError(RopeError):

113

"""

114

Raised when history operations fail.

115

Can occur during undo/redo operations or history corruption.

116

"""

117

pass

118

```

119

120

## Error Handling Patterns

121

122

### Basic Exception Handling

123

124

```python

125

from rope.base.project import Project

126

from rope.base.exceptions import RopeError, ResourceNotFoundError, RefactoringError

127

from rope.refactor.rename import Rename

128

129

project = Project('/path/to/project')

130

131

try:

132

# Attempt to get a resource

133

try:

134

myfile = project.get_resource('nonexistent.py')

135

except ResourceNotFoundError:

136

print("File not found, creating new file")

137

myfile = project.get_file('nonexistent.py')

138

myfile.write('# New file\n')

139

140

# Attempt refactoring with error handling

141

try:

142

renamer = Rename(project, myfile, 50)

143

old_name = renamer.get_old_name()

144

changes = renamer.get_changes('new_name')

145

project.do(changes)

146

print(f"Successfully renamed '{old_name}' to 'new_name'")

147

148

except RefactoringError as e:

149

print(f"Refactoring failed: {e}")

150

# Handle refactoring-specific errors

151

152

except BadIdentifierError as e:

153

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

154

# Handle identifier validation errors

155

156

except RopeError as e:

157

print(f"Rope error occurred: {e}")

158

# Handle any rope-specific error

159

160

except Exception as e:

161

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

162

# Handle unexpected errors

163

164

finally:

165

project.close()

166

```

167

168

### Module Loading Error Handling

169

170

```python

171

from rope.base.project import Project

172

from rope.base.exceptions import ModuleNotFoundError, ModuleSyntaxError, ModuleDecodeError

173

174

project = Project('/path/to/project')

175

176

try:

177

# Handle various module loading errors

178

try:

179

module = project.get_module('mymodule')

180

print(f"Module loaded: {module}")

181

182

except ModuleNotFoundError:

183

print("Module not found in project or Python path")

184

# Try alternative module names or create module

185

186

except ModuleSyntaxError as e:

187

print(f"Module has syntax errors: {e}")

188

# Report syntax issues to user

189

190

except ModuleDecodeError as e:

191

print(f"Cannot decode module file: {e}")

192

# Handle encoding issues

193

194

finally:

195

project.close()

196

```

197

198

### Task Interruption Handling

199

200

```python

201

from rope.base.project import Project

202

from rope.base.taskhandle import TaskHandle

203

from rope.base.exceptions import InterruptedTaskError

204

from rope.refactor.rename import Rename

205

206

def cancel_callback():

207

# Custom cancellation logic

208

return user_requested_cancel()

209

210

project = Project('/path/to/project')

211

212

try:

213

# Create task handle with cancellation support

214

task_handle = TaskHandle("Rename operation", cancel_callback)

215

216

try:

217

myfile = project.get_resource('mymodule.py')

218

renamer = Rename(project, myfile, 100)

219

changes = renamer.get_changes('new_name', task_handle=task_handle)

220

project.do(changes, task_handle)

221

print("Refactoring completed successfully")

222

223

except InterruptedTaskError:

224

print("Operation was cancelled by user")

225

# Clean up partial changes if necessary

226

227

finally:

228

project.close()

229

```

230

231

### Comprehensive Error Handling

232

233

```python

234

from rope.base.project import Project

235

from rope.base.exceptions import *

236

from rope.refactor.extract import ExtractMethod

237

238

def safe_refactor(project_path, file_path, start_offset, end_offset, method_name):

239

"""

240

Safely perform extract method refactoring with comprehensive error handling.

241

"""

242

project = None

243

try:

244

project = Project(project_path)

245

246

# Resource access with error handling

247

try:

248

resource = project.get_resource(file_path)

249

except ResourceNotFoundError:

250

return {"error": f"File not found: {file_path}"}

251

252

# Refactoring with error handling

253

try:

254

extractor = ExtractMethod(project, resource, start_offset, end_offset)

255

changes = extractor.get_changes(method_name)

256

257

# Validate changes before applying

258

description = changes.get_description()

259

print(f"About to apply: {description}")

260

261

project.do(changes)

262

return {"success": f"Extracted method '{method_name}'"}

263

264

except RefactoringError as e:

265

return {"error": f"Refactoring failed: {e}"}

266

267

except BadIdentifierError as e:

268

return {"error": f"Invalid method name '{method_name}': {e}"}

269

270

except InterruptedTaskError:

271

return {"error": "Operation was cancelled"}

272

273

except ModuleSyntaxError as e:

274

return {"error": f"Syntax error in file: {e}"}

275

276

except RopeError as e:

277

return {"error": f"Rope error: {e}"}

278

279

except Exception as e:

280

return {"error": f"Unexpected error: {e}"}

281

282

finally:

283

if project:

284

project.close()

285

286

# Usage

287

result = safe_refactor(

288

"/path/to/project",

289

"mymodule.py",

290

200, 350,

291

"extracted_method"

292

)

293

294

if "error" in result:

295

print(f"Error: {result['error']}")

296

else:

297

print(f"Success: {result['success']}")

298

```

299

300

### Error Recovery Patterns

301

302

```python

303

from rope.base.project import Project

304

from rope.base.exceptions import *

305

306

def robust_rename(project_path, file_path, offset, new_name, max_retries=3):

307

"""

308

Perform rename with automatic retry and error recovery.

309

"""

310

project = Project(project_path)

311

312

try:

313

resource = project.get_resource(file_path)

314

315

for attempt in range(max_retries + 1):

316

try:

317

from rope.refactor.rename import Rename

318

renamer = Rename(project, resource, offset)

319

320

# Validate before proceeding

321

try:

322

old_name = renamer.get_old_name()

323

print(f"Attempt {attempt + 1}: Renaming '{old_name}' to '{new_name}'")

324

except AttributeNotFoundError:

325

print("No identifier found at offset")

326

return False

327

328

changes = renamer.get_changes(new_name)

329

project.do(changes)

330

print("Rename successful")

331

return True

332

333

except BadIdentifierError as e:

334

print(f"Invalid identifier on attempt {attempt + 1}: {e}")

335

if attempt == max_retries:

336

print("All attempts failed - invalid identifier")

337

return False

338

# Could try with modified identifier

339

340

except RefactoringError as e:

341

print(f"Refactoring error on attempt {attempt + 1}: {e}")

342

if attempt == max_retries:

343

print("All attempts failed - refactoring error")

344

return False

345

# Could try with different parameters

346

347

except InterruptedTaskError:

348

print("Operation cancelled")

349

return False

350

351

except ResourceNotFoundError:

352

print(f"File not found: {file_path}")

353

return False

354

355

finally:

356

project.close()

357

358

return False

359

```

360

361

## Best Practices

362

363

### Exception Handling Guidelines

364

365

1. **Catch Specific Exceptions**: Always catch the most specific exception type first

366

2. **Resource Cleanup**: Use try/finally or context managers to ensure projects are closed

367

3. **User Feedback**: Provide meaningful error messages for different exception types

368

4. **Graceful Degradation**: Handle errors gracefully and provide fallback options

369

5. **Logging**: Log errors with sufficient context for debugging

370

371

### Common Error Scenarios

372

373

- **ResourceNotFoundError**: Check file existence before operations

374

- **RefactoringError**: Validate code structure before complex refactorings

375

- **BadIdentifierError**: Validate identifier names before rename operations

376

- **ModuleSyntaxError**: Parse and validate syntax before analysis

377

- **InterruptedTaskError**: Handle user cancellation in long operations