0
# Exception Handling
1
2
Comprehensive exception hierarchy for handling SOAP faults, transport errors, XML parsing issues, and validation failures. Zeep provides detailed error information to help diagnose and handle various failure scenarios.
3
4
## Capabilities
5
6
### Base Exception Classes
7
8
Foundation exception classes for all zeep-related errors.
9
10
```python { .api }
11
class Error(Exception):
12
def __init__(self, message: str = ""):
13
"""
14
Base exception for all zeep errors.
15
16
Parameters:
17
- message: Error description
18
"""
19
20
class ZeepWarning(RuntimeWarning):
21
"""Warning class for non-fatal zeep issues."""
22
```
23
24
### SOAP and Transport Errors
25
26
Exceptions related to SOAP communication and HTTP transport.
27
28
```python { .api }
29
class TransportError(Error):
30
def __init__(self, message: str = "", status_code: int = 0, content=None):
31
"""
32
HTTP transport error.
33
34
Parameters:
35
- message: Error description
36
- status_code: HTTP status code
37
- content: Response content
38
"""
39
40
class Fault(Error):
41
def __init__(
42
self,
43
message: str,
44
code: str = None,
45
actor: str = None,
46
detail=None,
47
subcodes: list = None
48
):
49
"""
50
SOAP fault response.
51
52
Parameters:
53
- message: Fault reason/description
54
- code: SOAP fault code
55
- actor: SOAP fault actor
56
- detail: Fault detail element
57
- subcodes: SOAP 1.2 fault subcodes
58
"""
59
```
60
61
### XML Processing Errors
62
63
Exceptions for XML parsing and processing issues.
64
65
```python { .api }
66
class XMLSyntaxError(Error):
67
def __init__(self, *args, content=None, **kwargs):
68
"""
69
XML syntax parsing error.
70
71
Parameters:
72
- content: XML content that caused the error
73
"""
74
75
class XMLParseError(Error):
76
def __init__(self, *args, filename: str = None, sourceline: int = None, **kwargs):
77
"""
78
XML parsing error with location information.
79
80
Parameters:
81
- filename: Source file name
82
- sourceline: Line number where error occurred
83
"""
84
85
class UnexpectedElementError(Error):
86
"""Unexpected XML element encountered during parsing."""
87
```
88
89
### WSDL Processing Errors
90
91
Exceptions related to WSDL document processing and validation.
92
93
```python { .api }
94
class WsdlSyntaxError(Error):
95
"""WSDL document syntax or structure error."""
96
97
class LookupError(Error):
98
def __init__(self, *args, qname: str = None, item_name: str = None, location: str = None, **kwargs):
99
"""
100
Namespace or element lookup failure.
101
102
Parameters:
103
- qname: Qualified name that failed lookup
104
- item_name: Item name being looked up
105
- location: Location context for lookup
106
"""
107
108
class NamespaceError(Error):
109
"""XML namespace processing error."""
110
```
111
112
### Validation and Schema Errors
113
114
Exceptions for XSD validation and schema processing.
115
116
```python { .api }
117
class ValidationError(Error):
118
def __init__(self, *args, path: list = None, **kwargs):
119
"""
120
XSD validation error with path information.
121
122
Parameters:
123
- path: List representing path to validation error
124
"""
125
126
class IncompleteMessage(Error):
127
"""SOAP message is incomplete or malformed."""
128
129
class IncompleteOperation(Error):
130
"""WSDL operation definition is incomplete."""
131
```
132
133
### Security-Related Errors
134
135
Exceptions for WS-Security and XML security processing.
136
137
```python { .api }
138
class SignatureVerificationFailed(Error):
139
"""Digital signature verification failed."""
140
141
class DTDForbidden(Error):
142
def __init__(self, name: str, sysid: str, pubid: str):
143
"""
144
DTD processing forbidden by security settings.
145
146
Parameters:
147
- name: DTD name
148
- sysid: System ID
149
- pubid: Public ID
150
"""
151
152
class EntitiesForbidden(Error):
153
def __init__(self, name: str, content: str):
154
"""
155
XML entities forbidden by security settings.
156
157
Parameters:
158
- name: Entity name
159
- content: Entity content
160
"""
161
```
162
163
## Usage Examples
164
165
### Basic Exception Handling
166
167
```python
168
from zeep import Client
169
from zeep.exceptions import Error, Fault, TransportError
170
171
client = Client('http://example.com/service.wsdl')
172
173
try:
174
result = client.service.SomeOperation(param='value')
175
except Fault as fault:
176
print(f"SOAP Fault: {fault.message}")
177
print(f"Fault Code: {fault.code}")
178
if fault.detail:
179
print(f"Fault Detail: {fault.detail}")
180
except TransportError as error:
181
print(f"Transport Error: {error.message}")
182
print(f"HTTP Status: {error.status_code}")
183
print(f"Response: {error.content}")
184
except Error as error:
185
print(f"Zeep Error: {error.message}")
186
```
187
188
### Handling Different Error Types
189
190
```python
191
from zeep import Client
192
from zeep.exceptions import (
193
XMLSyntaxError, XMLParseError, WsdlSyntaxError,
194
ValidationError, TransportError
195
)
196
197
try:
198
client = Client('http://example.com/problematic-service.wsdl')
199
result = client.service.ComplexOperation(
200
complex_param={
201
'required_field': 'value',
202
'optional_field': None
203
}
204
)
205
except WsdlSyntaxError as error:
206
print(f"WSDL has syntax errors: {error}")
207
# Handle malformed WSDL document
208
except XMLSyntaxError as error:
209
print(f"XML syntax error: {error}")
210
if error.content:
211
print(f"Problematic content: {error.content[:200]}...")
212
except XMLParseError as error:
213
print(f"XML parsing failed: {error}")
214
if error.filename and error.sourceline:
215
print(f"Location: {error.filename}:{error.sourceline}")
216
except ValidationError as error:
217
print(f"Validation failed: {error}")
218
if error.path:
219
path_str = '.'.join(str(p) for p in error.path)
220
print(f"Error path: {path_str}")
221
except TransportError as error:
222
if error.status_code == 404:
223
print("Service endpoint not found")
224
elif error.status_code == 500:
225
print("Server error occurred")
226
else:
227
print(f"HTTP error {error.status_code}: {error.message}")
228
```
229
230
### Security Exception Handling
231
232
```python
233
from zeep import Client, Settings
234
from zeep.exceptions import DTDForbidden, EntitiesForbidden, SignatureVerificationFailed
235
236
# Strict security settings
237
settings = Settings(
238
forbid_dtd=True,
239
forbid_entities=True,
240
forbid_external=True
241
)
242
243
try:
244
client = Client('http://example.com/service.wsdl', settings=settings)
245
result = client.service.SecureOperation(param='value')
246
except DTDForbidden as error:
247
print(f"DTD processing blocked: {error}")
248
print(f"DTD name: {error.name}, System ID: {error.sysid}")
249
except EntitiesForbidden as error:
250
print(f"XML entities blocked: {error}")
251
print(f"Entity name: {error.name}")
252
except SignatureVerificationFailed as error:
253
print(f"Digital signature verification failed: {error}")
254
# Handle authentication/integrity failure
255
```
256
257
### Comprehensive Error Handling
258
259
```python
260
import logging
261
from zeep import Client
262
from zeep.exceptions import *
263
264
logging.basicConfig(level=logging.INFO)
265
logger = logging.getLogger(__name__)
266
267
def safe_soap_call(wsdl_url, operation_name, **params):
268
"""Safely call SOAP operation with comprehensive error handling."""
269
270
try:
271
client = Client(wsdl_url)
272
operation = getattr(client.service, operation_name)
273
return operation(**params)
274
275
except Fault as fault:
276
logger.error(f"SOAP Fault in {operation_name}: {fault.message}")
277
if fault.code:
278
logger.error(f"Fault code: {fault.code}")
279
if fault.detail:
280
logger.error(f"Fault detail: {fault.detail}")
281
raise
282
283
except TransportError as error:
284
logger.error(f"Transport error in {operation_name}: {error.message}")
285
logger.error(f"HTTP status: {error.status_code}")
286
287
if error.status_code >= 500:
288
logger.error("Server error - may be temporary")
289
elif error.status_code >= 400:
290
logger.error("Client error - check request parameters")
291
292
raise
293
294
except ValidationError as error:
295
logger.error(f"Validation error in {operation_name}: {error}")
296
if error.path:
297
path_str = '.'.join(str(p) for p in error.path)
298
logger.error(f"Validation failed at: {path_str}")
299
raise
300
301
except WsdlSyntaxError as error:
302
logger.error(f"WSDL syntax error: {error}")
303
logger.error("The WSDL document is malformed")
304
raise
305
306
except XMLSyntaxError as error:
307
logger.error(f"XML syntax error: {error}")
308
if error.content:
309
logger.debug(f"Problematic XML: {error.content}")
310
raise
311
312
except LookupError as error:
313
logger.error(f"Lookup error in {operation_name}: {error}")
314
if error.qname:
315
logger.error(f"Failed to find: {error.qname}")
316
raise
317
318
except Error as error:
319
logger.error(f"General zeep error in {operation_name}: {error}")
320
raise
321
322
except Exception as error:
323
logger.error(f"Unexpected error in {operation_name}: {error}")
324
raise
325
326
# Usage
327
try:
328
result = safe_soap_call(
329
'http://example.com/service.wsdl',
330
'ComplexOperation',
331
param1='value1',
332
param2='value2'
333
)
334
print(f"Success: {result}")
335
except Error:
336
print("SOAP operation failed - see logs for details")
337
```
338
339
### Custom Error Handling with Retry Logic
340
341
```python
342
import time
343
from zeep import Client
344
from zeep.exceptions import TransportError, Error
345
346
def resilient_soap_call(client, operation_name, max_retries=3, **params):
347
"""SOAP call with retry logic for transient errors."""
348
349
for attempt in range(max_retries + 1):
350
try:
351
operation = getattr(client.service, operation_name)
352
return operation(**params)
353
354
except TransportError as error:
355
if error.status_code >= 500 and attempt < max_retries:
356
wait_time = 2 ** attempt # Exponential backoff
357
print(f"Server error (attempt {attempt + 1}), retrying in {wait_time}s...")
358
time.sleep(wait_time)
359
continue
360
else:
361
print(f"Transport error after {attempt + 1} attempts: {error}")
362
raise
363
364
except Error as error:
365
print(f"Non-recoverable error: {error}")
366
raise
367
368
# Usage
369
client = Client('http://example.com/service.wsdl')
370
try:
371
result = resilient_soap_call(
372
client,
373
'UnreliableOperation',
374
max_retries=3,
375
param='value'
376
)
377
except Error as e:
378
print(f"Operation failed permanently: {e}")
379
```