0
# Exception Handling
1
2
Comprehensive error handling for compilation failures and system issues. The py-solc library provides structured exceptions that give detailed information about what went wrong during compilation or installation.
3
4
## Exception Classes
5
6
### SolcError
7
8
Base exception class for all solc-related errors.
9
10
```python { .api }
11
class SolcError(Exception):
12
"""
13
Base exception for solc compilation errors.
14
15
Attributes:
16
command (list): Command that failed
17
return_code (int): Process return code
18
stdin_data (str): Input data sent to process (or None)
19
stdout_data (str): Process stdout output (or None)
20
stderr_data (str): Process stderr output (or None)
21
message (str): Error message
22
"""
23
24
def __init__(self, command, return_code, stdin_data, stdout_data, stderr_data, message=None):
25
"""
26
Initialize SolcError with process information.
27
28
Args:
29
command (list): The solc command that was executed
30
return_code (int): Process exit code
31
stdin_data: Data sent to stdin (converted to string)
32
stdout_data: Process stdout (converted to string)
33
stderr_data: Process stderr (converted to string)
34
message (str): Custom error message (optional)
35
"""
36
```
37
38
### ContractsNotFound
39
40
Specific exception raised when no contracts are found during compilation.
41
42
```python { .api }
43
class ContractsNotFound(SolcError):
44
"""
45
Raised when no contracts are found during compilation.
46
47
This exception inherits all attributes from SolcError.
48
Default message: "No contracts found during compilation"
49
"""
50
```
51
52
## Usage Examples
53
54
### Basic Exception Handling
55
56
```python
57
from solc import compile_source, SolcError
58
59
try:
60
result = compile_source('''
61
pragma solidity ^0.4.24;
62
contract BrokenContract {
63
// Syntax error: missing semicolon
64
uint256 value = 42
65
}
66
''')
67
except SolcError as e:
68
print(f"Compilation failed: {e}")
69
print(f"Command: {' '.join(e.command)}")
70
print(f"Return code: {e.return_code}")
71
if e.stderr_data:
72
print(f"Error output: {e.stderr_data}")
73
```
74
75
### Handling ContractsNotFound
76
77
```python
78
from solc import compile_source, ContractsNotFound
79
80
try:
81
# Source with no contracts (just comments)
82
result = compile_source('''
83
pragma solidity ^0.4.24;
84
// This file contains no contracts
85
''')
86
except ContractsNotFound as e:
87
print("No contracts found in the source code")
88
print(f"Source code processed: {e.stdin_data[:100]}...")
89
90
# Allow empty compilation instead
91
result = compile_source('''
92
pragma solidity ^0.4.24;
93
// This file contains no contracts
94
''', allow_empty=True)
95
print(f"Empty compilation result: {result}")
96
```
97
98
### Specific Error Handling by Type
99
100
```python
101
from solc import compile_standard, SolcError, ContractsNotFound
102
103
def safe_compile(source_code):
104
try:
105
return compile_standard({
106
'language': 'Solidity',
107
'sources': {
108
'contract.sol': {'content': source_code}
109
},
110
'settings': {
111
'outputSelection': {
112
'*': {'*': ['abi', 'evm.bytecode']}
113
}
114
}
115
})
116
except ContractsNotFound as e:
117
print("Warning: No contracts found in source")
118
return None
119
except SolcError as e:
120
if e.return_code == 1:
121
print("Compilation error (syntax/semantic issues)")
122
elif e.return_code == 2:
123
print("Solc internal error")
124
else:
125
print(f"Unknown solc error (code {e.return_code})")
126
127
# Try to extract detailed error information
128
if e.stdout_data:
129
try:
130
import json
131
output = json.loads(e.stdout_data)
132
if 'errors' in output:
133
for error in output['errors']:
134
print(f" {error.get('severity', 'error')}: {error.get('message', 'Unknown error')}")
135
except (json.JSONDecodeError, KeyError):
136
print(f"Raw error output: {e.stderr_data}")
137
138
return None
139
```
140
141
### Installation Error Handling
142
143
```python
144
from solc import install_solc
145
146
def safe_install(version, platform=None):
147
try:
148
install_solc(version, platform=platform)
149
print(f"Successfully installed solc {version}")
150
except ValueError as e:
151
print(f"Invalid version or platform: {e}")
152
except OSError as e:
153
print(f"System error during installation: {e}")
154
# Check common issues
155
if "git" in str(e).lower():
156
print("Make sure git is installed and available in PATH")
157
elif "permission" in str(e).lower():
158
print("Permission denied - check write access to ~/.py-solc/")
159
elif "network" in str(e).lower() or "download" in str(e).lower():
160
print("Network error - check internet connection")
161
except Exception as e:
162
print(f"Unexpected error: {e}")
163
print("Please check system requirements and try again")
164
```
165
166
### Comprehensive Error Analysis
167
168
```python
169
from solc import compile_source, SolcError, ContractsNotFound
170
171
def analyze_compilation_error(source_code):
172
try:
173
result = compile_source(source_code)
174
return result
175
except ContractsNotFound as e:
176
return {
177
'success': False,
178
'error_type': 'no_contracts',
179
'message': 'No contracts found in source code',
180
'suggestion': 'Make sure your source code defines at least one contract'
181
}
182
except SolcError as e:
183
error_info = {
184
'success': False,
185
'error_type': 'compilation_error',
186
'return_code': e.return_code,
187
'command': e.command,
188
'message': str(e)
189
}
190
191
# Analyze stderr for common issues
192
if e.stderr_data:
193
stderr_lower = e.stderr_data.lower()
194
if 'parsererror' in stderr_lower:
195
error_info['category'] = 'syntax_error'
196
error_info['suggestion'] = 'Check for syntax errors like missing semicolons, brackets, etc.'
197
elif 'typeerror' in stderr_lower:
198
error_info['category'] = 'type_error'
199
error_info['suggestion'] = 'Check variable types and function signatures'
200
elif 'declarationerror' in stderr_lower:
201
error_info['category'] = 'declaration_error'
202
error_info['suggestion'] = 'Check for undeclared variables or duplicate declarations'
203
elif 'not found' in stderr_lower:
204
error_info['category'] = 'import_error'
205
error_info['suggestion'] = 'Check file paths and import statements'
206
else:
207
error_info['category'] = 'unknown_compilation_error'
208
error_info['suggestion'] = 'Review the full error message for details'
209
210
return error_info
211
212
# Usage
213
result = analyze_compilation_error('''
214
pragma solidity ^0.4.24;
215
contract Test {
216
uint256 value = ; // Syntax error
217
}
218
''')
219
220
if not result['success']:
221
print(f"Error: {result['message']}")
222
print(f"Suggestion: {result['suggestion']}")
223
```
224
225
### Exception Information Access
226
227
```python
228
from solc import compile_source, SolcError
229
230
try:
231
compile_source("invalid solidity code")
232
except SolcError as e:
233
print("Exception Details:")
234
print(f" Message: {e.message}")
235
print(f" Command: {' '.join(e.command) if e.command else 'None'}")
236
print(f" Return Code: {e.return_code}")
237
print(f" Has stdin data: {e.stdin_data is not None}")
238
print(f" Has stdout data: {e.stdout_data is not None}")
239
print(f" Has stderr data: {e.stderr_data is not None}")
240
241
if e.stdin_data:
242
print(f" Input (first 100 chars): {e.stdin_data[:100]}...")
243
244
if e.stdout_data:
245
print(f" Stdout (first 200 chars): {e.stdout_data[:200]}...")
246
247
if e.stderr_data:
248
print(f" Stderr: {e.stderr_data}")
249
```
250
251
## Error Categories
252
253
### Compilation Errors (SolcError)
254
255
These occur when solc itself fails to compile the Solidity code:
256
257
- **Syntax Errors**: Missing semicolons, unmatched brackets, etc.
258
- **Type Errors**: Incorrect variable types, invalid casts, etc.
259
- **Declaration Errors**: Undeclared variables, duplicate names, etc.
260
- **Import Errors**: Missing files, circular imports, etc.
261
- **Version Errors**: Pragma version mismatches, unsupported features
262
263
### Contract Discovery Errors (ContractsNotFound)
264
265
These occur when compilation succeeds but no contracts are found:
266
267
- Empty source files
268
- Files with only comments
269
- Files with only imports or libraries
270
- Source files with syntax that prevents contract detection
271
272
### System Errors (OSError, ValueError)
273
274
These occur due to system-level issues:
275
276
- **Installation Errors**: Network issues, permission problems, missing dependencies
277
- **Binary Errors**: Corrupted solc binary, wrong architecture
278
- **File System Errors**: Permission denied, disk full, invalid paths
279
280
## Best Practices
281
282
### 1. Always Handle Specific Exceptions
283
284
```python
285
try:
286
result = compile_source(source)
287
except ContractsNotFound:
288
# Handle specifically
289
pass
290
except SolcError:
291
# Handle compilation errors
292
pass
293
except Exception:
294
# Handle unexpected errors
295
pass
296
```
297
298
### 2. Provide Meaningful Error Messages
299
300
```python
301
try:
302
result = compile_source(source)
303
except SolcError as e:
304
user_message = f"Failed to compile Solidity code: {e.message}"
305
if "ParserError" in str(e):
306
user_message += "\nPlease check your syntax for missing semicolons or brackets."
307
raise RuntimeError(user_message) from e
308
```
309
310
### 3. Log Detailed Information for Debugging
311
312
```python
313
import logging
314
315
try:
316
result = compile_source(source)
317
except SolcError as e:
318
logging.error(f"Solc compilation failed:")
319
logging.error(f" Command: {' '.join(e.command)}")
320
logging.error(f" Return code: {e.return_code}")
321
logging.error(f" Stderr: {e.stderr_data}")
322
raise
323
```
324
325
### 4. Graceful Degradation
326
327
```python
328
def try_compile_with_fallback(source):
329
try:
330
return compile_source(source)
331
except ContractsNotFound:
332
# Try with allow_empty
333
return compile_source(source, allow_empty=True)
334
except SolcError as e:
335
if "version" in str(e).lower():
336
# Try without pragma version
337
source_no_pragma = re.sub(r'pragma solidity[^;]*;', '', source)
338
return compile_source(source_no_pragma)
339
raise
340
```