0
# Error System
1
2
Comprehensive error handling system including error definitions, classification, filtering, and formatting for various output targets.
3
4
## Capabilities
5
6
### Core Error Classes
7
8
The foundational classes that represent analysis findings and organize them into a hierarchical classification system.
9
10
```python { .api }
11
class Error:
12
"""
13
Base class for all refurb analysis findings.
14
15
Each Error represents a specific code improvement opportunity found during analysis.
16
Contains location information, descriptive message, and classification metadata.
17
18
Attributes:
19
- line: int - Line number where issue was found (1-based)
20
- column: int - Column position where issue starts (0-based)
21
- msg: str - Human-readable description of the issue and suggested improvement
22
- filename: str | None - Source file path (None for synthetic errors)
23
- line_end: int | None - End line number for multi-line issues
24
- column_end: int | None - End column position for multi-line issues
25
26
Class attributes:
27
- enabled: bool - Whether check is enabled by default
28
- name: str - Human-readable name for the check
29
- prefix: str - Error code prefix (e.g., "FURB")
30
- categories: set[str] - Categories this error belongs to
31
- code: int - Unique numeric identifier for this error type
32
"""
33
line: int
34
column: int
35
msg: str
36
filename: str | None
37
line_end: int | None
38
column_end: int | None
39
40
@classmethod
41
def from_node(cls, node: Node, msg: str | None = None) -> Error:
42
"""
43
Create Error instance from AST node.
44
45
Convenience method that extracts position information from AST node
46
and creates Error with appropriate line/column information.
47
48
Parameters:
49
- node: AST node to extract position from
50
- msg: Optional custom message (uses class default if None)
51
52
Returns:
53
Error instance with node position information
54
"""
55
56
class ErrorCode:
57
"""
58
Identifier for specific error types, used in configuration and filtering.
59
60
Attributes:
61
- id: int - Numeric error identifier
62
- prefix: str - Error prefix (e.g., "FURB")
63
- path: str | None - Module path for plugin errors
64
"""
65
id: int
66
prefix: str
67
path: str | None
68
69
class ErrorCategory:
70
"""
71
Category grouping for related error types, enabling bulk configuration.
72
73
Attributes:
74
- value: str - Category name (e.g., "readability", "pathlib")
75
- path: str | None - Module path for plugin categories
76
"""
77
value: str
78
path: str | None
79
```
80
81
### Error Classification
82
83
Type definitions and utilities for organizing and filtering errors.
84
85
```python { .api }
86
ErrorClassifier = ErrorCategory | ErrorCode
87
"""Union type representing either a specific error code or error category."""
88
89
@classmethod
90
def from_error(cls, error: type[Error]) -> ErrorCode:
91
"""
92
Create ErrorCode from Error class.
93
94
Parameters:
95
- error: Error class to extract code from
96
97
Returns:
98
ErrorCode instance with id, prefix, and path from error class
99
"""
100
```
101
102
### Error Explanation System
103
104
Functions that provide detailed explanations and documentation for error codes.
105
106
```python { .api }
107
def explain(settings: Settings) -> str:
108
"""
109
Generate detailed explanation for specified error code.
110
111
Provides comprehensive documentation including:
112
- Description of what the error detects
113
- Examples of problematic code patterns
114
- Suggested improvements and modern alternatives
115
- Related error codes and categories
116
117
Parameters:
118
- settings: Settings object with explain field specifying error code
119
120
Returns:
121
Formatted explanation text ready for display
122
"""
123
```
124
125
### Built-in Error Categories
126
127
Refurb organizes its 94 built-in checks into focused categories:
128
129
**Core Python Improvements:**
130
- `builtin` (21 checks): Core Python builtin function usage
131
- `readability` (22 checks): Code clarity and Pythonic patterns
132
- `flow` (4 checks): Control flow optimization
133
- `logical` (3 checks): Logical expression simplification
134
135
**Standard Library Modernization:**
136
- `pathlib` (15 checks): Modern path manipulation with pathlib
137
- `string` (7 checks): String operation optimization
138
- `iterable` (3 checks): Iterable processing improvements
139
- `datetime` (2 checks): Date and time handling
140
- `itertools` (2 checks): Iterator tool usage
141
- `math` (2 checks): Mathematical operation optimization
142
- `regex` (2 checks): Regular expression improvements
143
- `hashlib` (2 checks): Hashing function usage
144
145
**Specialized Improvements:**
146
- `collections` (1 check): Collection type improvements
147
- `contextlib` (1 check): Context manager usage
148
- `decimal` (1 check): Decimal arithmetic
149
- `function` (1 check): Function definition improvements
150
- `functools` (1 check): Functional programming patterns
151
- `pattern_matching` (1 check): Pattern matching optimization
152
- `secrets` (1 check): Secure random number generation
153
- `shlex` (1 check): Shell lexing improvements
154
155
**Third-party Integration:**
156
- `third_party/fastapi` (1 check): FastAPI-specific patterns
157
158
### Error Code Examples
159
160
Common error codes and their meanings:
161
162
- `FURB105`: Replace `open` and `read` with `pathlib.Path.read_text()`
163
- `FURB123`: Replace `type(x) is type(y)` with `isinstance(x, type(y))`
164
- `FURB131`: Replace `del dict[key]` with `dict.pop(key, None)`
165
- `FURB140`: Replace `import os; os.path.exists()` with `pathlib.Path.exists()`
166
- `FURB161`: Replace `int(x, 0)` with `int(x)`
167
168
### Usage Examples
169
170
```python
171
from refurb.error import Error, ErrorCode, ErrorCategory
172
173
# Define custom error class
174
class MyCustomError(Error):
175
enabled = True
176
name = "Use modern API"
177
prefix = "FURB"
178
categories = {"readability"}
179
code = 999
180
181
# Create error instance
182
error = MyCustomError(
183
line=10,
184
column=5,
185
msg="Replace `old_function()` with `new_function()`",
186
filename="example.py"
187
)
188
189
# Work with error codes
190
error_code = ErrorCode(id=105, prefix="FURB", path=None)
191
category = ErrorCategory(value="pathlib", path=None)
192
193
# Check error classification
194
assert ErrorCode.from_error(MyCustomError).id == 999
195
```
196
197
### Integration with Configuration
198
199
Errors integrate with the configuration system for flexible filtering:
200
201
```python
202
# Settings-based error filtering
203
settings = Settings(
204
ignore={ErrorCode(105, "FURB", None)}, # Ignore FURB105
205
enable={ErrorCategory("pathlib", None)}, # Enable all pathlib checks
206
disable={ErrorCategory("readability", None)} # Disable readability checks
207
)
208
```
209
210
### Plugin Error Support
211
212
The error system supports plugin-defined errors with custom prefixes and categories:
213
214
```python
215
# Plugin error with custom prefix
216
class PluginError(Error):
217
enabled = True
218
name = "Plugin check"
219
prefix = "PLUG" # Custom prefix
220
categories = {"plugin-category"}
221
code = 1
222
223
# Results in error code PLUG001
224
```