I was having a discussion about this with a co-worker and we couldn't come to an agreement, so I wanted to get your thoughts. I have my own opinions on this, but I won't spoil it for you.
When should I be returning a SOAP fault and when should I be returning a result object that has error information? Assume this is for a generic web service that can be consumed by various systems (.NET, Java, whatever). The result object would have an isError flag, an errorType (similar to specific exception type), and a message.
Some points to consider:
Links to articles are valid. Even though it sounds like I want your opinion, please stick to facts (x is better because of y and z...)
A SOAP fault is an error in a SOAP (Simple Object Access Protocol) communication resulting from incorrect message format, header-processing problems, or incompatibility between applications.
The basic structure of the fault message is defined in the SOAP specifications. Each fault message can include XML that describes the specific error condition. For example, if an application abend occurs in a CICS web service, a fault message is returned to the client reporting the abend.
SOAP faults are generated by receivers to report business logic errors or unexpected conditions. In JAX-WS, Java exceptions ( java. lang. Exception ) that are thrown by your Java Web service are mapped to a SOAP fault and returned to the client to communicate the reason for failure.
Most SOAP clients will convert faults into a runtime exception (if that is something the client language supports). With that in mind, I think you could rephrase the question as "When do I want to throw an exception instead of returning an error value"? I'm sure you can find lots of opinions about that API design in general and that topic in particular.
That said, returning an error is usually not helpful to the client:
The client needs to manually enumerate and handle your error codes vs. allowing the stub code to generate and throw an exception of the appropriate type. Using error codes prevents the client from using object-oriented techniques like handling exceptions by superclass.
If you don't make your error codes part of the WSDL; the client will have no documentation on what they are or when they occur. Typed faults are part of the WSDL and therefore (to some limited extent) self-documenting.
Fault messages can contain fault-specific context that the client can make use of for error reporting and recovery. For example, throwing an input validation fault containing the actual invalid input element and a reason. If you return a result with an error code and an opaque string, the client has little choice but to pass your error message on to the user, which breaks internationalization, UI consistency, etc.
To answer your specific questions:
A validation error is a fault. Imagine if you invoke the web service from an AJAX client with limited error handling ability; you want the service to return a 5xx HTTP code, not a 400 success code with some unexpected response.
No. APIs should provide consistent error reporting interfaces. WSDL design is API design. Forcing the client to implement two distinct error handlers does not make the client's life easier.
Fault design should mirror your request/response model and display information appropriate to the abstraction of the service. Don't design a NullReference fault; design a XYZServiceRuntimeFault. If clients frequently provide invalid requests, design a InvalidRequestFault, with appropriate subclasses so that clients can quickly figure out where the invalid data is.
A results object should only contain results. If your result object is providing a list of errors that have occurred on another system then that is an example of when you can have and "isError" flag; otherwise you can't because a result is either valid or not.
You should always be using a SOAPFault when an error occurs. Validation is an error, and it's the devils own trap to think of validation as being less severe than an inability to open a database. Both cases have the same impact - the operation cannot be completed as requested.
So you should use result objects for results and SOAP Faults for anything that prevents a valid result object; including but not limited to errors, validation failures, warnings, bus faults, etc..
In the days before exceptions there was no choice and as a result many APIs became inconsistent and most APIs differed on how to return an error. It was (and still is) horrible, confusing and often slows down development because you have to lookup how each API entry returns an error, and often how to decode or find out more about the error.
To handle validation with SOAPFaults / Exceptions is more logical when you think about it, and once you've thought about it is usually easier. You do need to design the validation fault class so that it contains sufficient information to identify the offending elements in a manner not necessarily requiring the original request. This way you can start to handle validation errors more generically.
If the results object contains errors they can only be within the domain of the results; for example Product out of stock because someone in the wharehouse can't count is within the domain of inventory control.
It is not wise to make the distinction between a critical error and a validation error, this to my mind isn't a valid comparison because any assignation of severity level is very subjective. For example in a system providing information about chemicals to a firefighter, critical probably means that the truck on fire is carrying UN 1298 & UN 1436 and not a null reference when attempting to load the warning graphic.
Design the faults in to allow them to be identified concisely and handled accordingly. Ensure that they convey sufficient information. Abritrary categorisation is something that is unncessary when you've got sufficient information because the Fault will allow itself to be indentified.
SOAPFaults turned into Exceptions are the surest way of having fail-fast.
Best practices, references etc.
Managing Exceptions in a SOA world: Ramesh Ranganathan
When Exceptions Are the Rule : Achieving reliable and traceable service-oriented architectures
Best practices on SOAP Faults
Use SOAP Faults to deliver the appropriate level of detail to the developer at development time, and to the customer while the Web service is in production.
Web services use SOAP faults to report fault cases back to clients. The faults can be generated from the SOAP framework in a case of invalid SOAP messages, invalid security tokens or they can be generated from the service business logic itself
If you send a message that was not successful for some reason, you may get back a response containing a SOAP fault element, which gives you status information, error information, or both. There can be only one SOAP fault element in a message, and it must be an entry in the SOAP body. Furthermore, if there is a SOAP fault element in the SOAP body, there can be no other elements in the SOAP body. This means that when you add a SOAP fault element, you have effectively completed the construction of the SOAP body.
SOAP fault messages are the mechanism by which SOAP applications report errors “upstream,” to nodes earlier in the message path. It's the mission of this section to provide a full and detailed explanation of SOAP faults so that you can handle them appropriately in your own Web services.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With