0
# Exception Handling
1
2
Comprehensive exception hierarchy for handling compilation errors, installation failures, version mismatches, and configuration issues. All exceptions provide detailed error information including command output and diagnostic data.
3
4
## Capabilities
5
6
### Core Exceptions
7
8
Base exception classes that provide detailed error information and diagnostic data for troubleshooting.
9
10
```python { .api }
11
class SolcError(Exception):
12
"""
13
Base exception for solc execution errors.
14
15
Attributes:
16
- message: Error description
17
- command: Command that was executed
18
- return_code: Process return code
19
- stdin_data: Input data sent to process
20
- stdout_data: Process stdout output
21
- stderr_data: Process stderr output
22
- error_dict: Parsed error information (if available)
23
"""
24
25
def __init__(
26
self,
27
message: Optional[str] = None,
28
command: Optional[List[str]] = None,
29
return_code: Optional[int] = None,
30
stdin_data: Optional[str] = None,
31
stdout_data: Optional[str] = None,
32
stderr_data: Optional[str] = None,
33
error_dict: Optional[Dict] = None,
34
) -> None: ...
35
36
class ContractsNotFound(SolcError):
37
"""
38
Raised when no contracts found during compilation.
39
40
This typically occurs when:
41
- Source code contains no contract definitions
42
- All contracts have compilation errors
43
- Source files are empty or invalid
44
"""
45
```
46
47
Usage example:
48
49
```python
50
import solcx
51
from solcx import SolcError, ContractsNotFound
52
53
try:
54
# Invalid Solidity code
55
result = solcx.compile_source("invalid code here")
56
except ContractsNotFound:
57
print("No valid contracts found in source")
58
except SolcError as e:
59
print(f"Compilation failed: {e.message}")
60
print(f"Command: {' '.join(e.command)}")
61
print(f"Return code: {e.return_code}")
62
if e.stderr_data:
63
print(f"Error output: {e.stderr_data}")
64
```
65
66
### Installation Exceptions
67
68
Exceptions related to Solidity compiler installation, version management, and binary execution.
69
70
```python { .api }
71
class SolcInstallationError(Exception):
72
"""
73
Raised when solc installation fails.
74
75
Common causes:
76
- Network connectivity issues
77
- Invalid version specifications
78
- File system permissions
79
- Corrupted downloads
80
"""
81
82
class SolcNotInstalled(Exception):
83
"""
84
Raised when trying to use solc that isn't installed.
85
86
This occurs when:
87
- No solc versions are installed
88
- Specified version is not installed
89
- Installation directory is corrupted
90
"""
91
92
class UnexpectedVersionError(Exception):
93
"""
94
Raised when installed solc version doesn't match expected version.
95
96
This can happen when:
97
- Downloaded binary has different version than requested
98
- Binary is corrupted or modified
99
- Version metadata is incorrect
100
"""
101
102
class UnsupportedVersionError(ValueError):
103
"""
104
Raised when trying to use unsupported solc version.
105
106
py-solc-x supports solc versions >= 0.4.11
107
"""
108
109
class DownloadError(Exception):
110
"""
111
Raised when download fails during installation.
112
113
Common causes:
114
- Network connectivity issues
115
- Server errors (404, 500, etc.)
116
- GitHub API rate limiting
117
- Interrupted downloads
118
"""
119
```
120
121
Usage example:
122
123
```python
124
import solcx
125
from solcx import (
126
SolcNotInstalled,
127
SolcInstallationError,
128
UnsupportedVersionError,
129
DownloadError
130
)
131
132
# Handle missing installation
133
try:
134
solcx.set_solc_version('0.8.19')
135
except SolcNotInstalled:
136
print("Version 0.8.19 not installed, installing now...")
137
solcx.install_solc('0.8.19')
138
solcx.set_solc_version('0.8.19')
139
140
# Handle installation failures
141
try:
142
solcx.install_solc('0.8.99') # Non-existent version
143
except SolcInstallationError as e:
144
print(f"Installation failed: {e}")
145
except DownloadError as e:
146
print(f"Download failed: {e}")
147
148
# Handle unsupported versions
149
try:
150
solcx.install_solc('0.3.0') # Too old
151
except UnsupportedVersionError as e:
152
print(f"Version not supported: {e}")
153
```
154
155
### Compiler Option Exceptions
156
157
Exceptions for invalid compiler options and values, helping identify compatibility issues between different solc versions.
158
159
```python { .api }
160
class UnknownOption(AttributeError):
161
"""
162
Raised when using unsupported solc option.
163
164
Different solc versions support different command-line options.
165
This helps identify when an option isn't available in the active version.
166
"""
167
168
class UnknownValue(ValueError):
169
"""
170
Raised when using invalid value for solc option.
171
172
This occurs when an option exists but the provided value is not valid
173
for the current solc version.
174
"""
175
```
176
177
Usage example:
178
179
```python
180
import solcx
181
from solcx import UnknownOption, UnknownValue
182
183
try:
184
# This might fail with older solc versions
185
solcx.compile_source(
186
"pragma solidity ^0.4.0; contract Test {}",
187
metadata_hash='ipfs' # Not supported in very old versions
188
)
189
except UnknownOption as e:
190
print(f"Option not supported: {e}")
191
except UnknownValue as e:
192
print(f"Invalid option value: {e}")
193
```
194
195
### Warning Classes
196
197
Warning classes for non-fatal issues that don't prevent execution but may indicate problems.
198
199
```python { .api }
200
class UnexpectedVersionWarning(Warning):
201
"""
202
Warning for version mismatches that aren't fatal.
203
204
This is raised when:
205
- Installed binary version differs slightly from expected
206
- Nightly builds are detected
207
- Version metadata is ambiguous
208
"""
209
```
210
211
Usage example:
212
213
```python
214
import warnings
215
import solcx
216
from solcx import UnexpectedVersionWarning
217
218
# Capture version warnings
219
with warnings.catch_warnings(record=True) as w:
220
warnings.simplefilter("always")
221
222
# This might trigger a warning for nightly builds
223
solcx.install_solc('0.8.19')
224
225
for warning in w:
226
if issubclass(warning.category, UnexpectedVersionWarning):
227
print(f"Version warning: {warning.message}")
228
```
229
230
## Exception Handling Patterns
231
232
### Graceful Installation
233
234
Handle missing installations gracefully by automatically installing required versions:
235
236
```python
237
import solcx
238
from solcx import SolcNotInstalled
239
240
def ensure_solc_version(version):
241
"""Ensure a specific solc version is available."""
242
try:
243
solcx.set_solc_version(version)
244
except SolcNotInstalled:
245
print(f"Installing solc {version}...")
246
solcx.install_solc(version)
247
solcx.set_solc_version(version)
248
249
# Usage
250
ensure_solc_version('0.8.19')
251
```
252
253
### Compilation Error Analysis
254
255
Extract detailed error information from compilation failures:
256
257
```python
258
import solcx
259
from solcx import SolcError
260
261
def compile_with_error_analysis(source):
262
"""Compile source with detailed error reporting."""
263
try:
264
return solcx.compile_source(source)
265
except SolcError as e:
266
print("Compilation failed!")
267
print(f"Command: {' '.join(e.command)}")
268
print(f"Return code: {e.return_code}")
269
270
if e.stderr_data:
271
# Parse and display specific errors
272
error_lines = e.stderr_data.strip().split('\n')
273
for line in error_lines:
274
if 'Error:' in line or 'Warning:' in line:
275
print(f" {line}")
276
277
# Re-raise for caller to handle
278
raise
279
280
# Usage
281
source = '''
282
pragma solidity ^0.8.0;
283
contract Test {
284
uint256 invalid syntax here;
285
}
286
'''
287
288
try:
289
compiled = compile_with_error_analysis(source)
290
except SolcError:
291
print("Could not compile contract")
292
```
293
294
### Version Compatibility Checking
295
296
Check compatibility before performing operations:
297
298
```python
299
import solcx
300
from solcx import UnsupportedVersionError, UnknownOption
301
from packaging.version import Version
302
303
def compile_with_optimization(source, solc_version='0.8.19'):
304
"""Compile with optimization, handling version compatibility."""
305
# Ensure version is available
306
try:
307
solcx.set_solc_version(solc_version)
308
except:
309
solcx.install_solc(solc_version)
310
solcx.set_solc_version(solc_version)
311
312
# Check if optimization is supported
313
version_obj = Version(solc_version)
314
315
try:
316
if version_obj >= Version('0.5.0'):
317
# Modern optimization options
318
return solcx.compile_source(
319
source,
320
optimize=True,
321
optimize_runs=200
322
)
323
else:
324
# Basic optimization for older versions
325
return solcx.compile_source(source, optimize=True)
326
327
except UnknownOption as e:
328
print(f"Optimization not available: {e}")
329
# Fall back to basic compilation
330
return solcx.compile_source(source)
331
332
# Usage
333
result = compile_with_optimization(
334
"pragma solidity ^0.8.0; contract Test { uint256 public value = 42; }",
335
'0.8.19'
336
)
337
```
338
339
### Network Error Handling
340
341
Handle network-related errors during installation:
342
343
```python
344
import time
345
import solcx
346
from solcx import DownloadError, SolcInstallationError
347
348
def install_solc_with_retry(version, max_retries=3):
349
"""Install solc with retry logic for network errors."""
350
for attempt in range(max_retries):
351
try:
352
return solcx.install_solc(version)
353
except DownloadError as e:
354
if attempt == max_retries - 1:
355
raise
356
print(f"Download failed (attempt {attempt + 1}): {e}")
357
print(f"Retrying in {2 ** attempt} seconds...")
358
time.sleep(2 ** attempt)
359
except SolcInstallationError as e:
360
if "network" in str(e).lower() or "connection" in str(e).lower():
361
if attempt == max_retries - 1:
362
raise
363
print(f"Network error (attempt {attempt + 1}): {e}")
364
time.sleep(2 ** attempt)
365
else:
366
# Non-network error, don't retry
367
raise
368
369
# Usage
370
try:
371
version = install_solc_with_retry('0.8.19')
372
print(f"Successfully installed: {version}")
373
except Exception as e:
374
print(f"Failed to install after retries: {e}")
375
```