BizTalk behaviour Http Send Adaptor when receiving a 400 or 500 - biztalk

If my Http Send adaptor receives an http 500 I want to retry. If it returns a 400 I don't want it to retry. Instead I want to subscribe to the message and email it somewhere.
It seems that the Http Send adaptor automatically retries in everything but a 200 and when it is a 400 or 500 does not appear to publish the response message. Am I missing something here?

Unfortunately that is it's expected behaviour. It is something I wrote about as a missing feature in my blog article BizTalk 2013 R2 known bugs, issues & quirks (excerpt below), as there was also an issue with the way it throws the error after the retries have finished. The workaround would be to set retries to zero and have an Orchestration or code another retry mechanism.
MISSING: BIZTALK WCF-WEBHTTP ADAPTER ABILITY TO SUPPRESS 404 STATUS CODE
Details: When you do a get on a RESTful service and get a 404 status code and a payload saying that the object you asked for does not exists, it will throw a SOAP exception. It would be nice to be able to suppress a 404 status code (or other status codes) on a GET (or other operations) and to parse the response as normal through the pipeline and process as business exception rather than a System Exception.
Work around: Catch the exception in an Orchestration and look for the not found error description that the service threw.

Related

Which HTTP status code should be used for business errors in API design?

Lets say I have an API endpoint that executes some business operation which can result in many different failures that are not connected directly to the request.
The request is correctly formed and I cannot return 4xx failures, but the logic of the application dictates that I return different error messages.
Now I want the client to be able to differentiate these error messages so that different actions can be taken depending on the code. I can return a custom JSON like this e.g.
{
"code": 15,
"message": "Some business error has occurred"
}
Now the question is which HTTP status code should I use for such occasions if no standard code like Conflict or NotFound makes sense.
It seems that 500 InternalServerError is logical, but then how can I additionally flag that this cannot be retried, should it be just documented that given status codes is not possible to retry so one can retry if you don't get one of those?
Consult RFC 7231:
503 Service Unavailable looks like a potential candidate, but the RFC mentions that this is supposed to represent a problem "which will likely be alleviated after some delay." This would indicate to a client that it could try the same call later, maybe after business hours or on the weekend. This is not what you want.
501 Not Implemented could be possible, but the RFC mentions "This
is the appropriate response when the server does not recognize the
request method and is not capable of supporting it for any resource. A 501 response is cacheable by default;" This does not appear to be the case here - the HTTP method itself was presumably valid - the failure here seems to be happening at the business rules layer (e.g. sending in an account number that is not in the database), rather than an HTTP method (GET, POST, etc.) that you never got around to implementing.
That leaves the last serious candidate,
500 Internal Server Error
The 500 (Internal Server Error) status code indicates that the server
encountered an unexpected condition that prevented it from fulfilling
the request.
This is the error code that is normally used for generic "an exception occurred in the app" situations. 500 is the best choice.
As to how to distinguish this from a "temporal internal trouble" error, you can include this as part of the HTTP body - just make sure that your client can parse out the custom codes!

Timeout in two-way receive port when redirecting failed messages

I've a two-way WCF receive port, where i've checked both:
1) Route failed messages
2) Suspend request message on failure
This configuration is needed to redirect failed messages to our "exception portal".
When a message is received and it fails validation in XMLReceive pipeline, the message is redirected to our "exception portal" as expected.
The problem is however that the consumer of the WCF service never get's a fault, so the Connection gets a timeout after a while, which is very confusing for the consumer.
Is there anyway to fix this problem? Am I missing something?
What's happening currently is that the message fails on the Receive pipeline, gets routed to your portal, but no response gets routed back. You have to make sure to send a message back. You could do that by:
creating an Orchestration that does the validation (instead of doing it on the pipeline), and making sure to send a response int he orchestration as well as routing failures to your portal
creating a custom component that validates the message (perhaps by calling the XML Validation pipeline in a try block and catching the exception without rethrowing it); on error it sends the message to your portal, and replaces pInMsg with something sensible to send back to the partner.
having your portal receive location be a request response port (perhaps, again, with an orchestration behind it), and route the response back to the WCF two way port. This way is more involved, and to be honest I'm not entirely sure what a working implementation would look like here, but it may be possible.
If it were up to me, I'd go for the Orchestration. You can certainly call the XML Validator pipeline from an orchestration, or you could use other validation logic in there (for example calling BRE).

What is the correct HTTP status for exceptions?

What HTTP status should I return if my script throws an exception?
200 OK
or
500 Internal Server Error
Let's say user request parameters are correct but there is a bug in my script which causes an error message to appear instead of a proper response (XML, JSON or other format). What should be the HTTP status?
500 Internal Server Error is the correct status if the error can't be fixed by the client changing their request.
Use any of the 4XX statuses if the client might be able to fix their request to avoid the error (or 404 if the resource wasn't found).
200 OK is not the appropriate status in almost any error situation, because then the client thinks things are running normally (which they are not) and may continue to make the same error-causing requests.
Familiarize yourself with the available status codes in RFC2616 and find one that most appropriately fits the situation.
It depends on why the exception is thrown since they can be used for almost any error. If it's thrown because some id in the URI is not found in the database I'd say 404. On the other hand if it's because the database is down I would throw a 500. If an exception is thrown but the resulting page would still be useful to the user I would say return 200.
Review the Status Code Definitions. 500 or 400 should do for general issues, however, the more detailed you can be then the more useful the returned status will be.

Error handling in web service

How do you communicate an error to the web service consumer ?
For example, my web service has a function to insert employee into db.Suppose while inserting the data , the database gave an error,what should be the best way to inform the user about the error.
One way is to depict it through the return value of the web service method but what to do when the function is supposed to return a complex object like employee when there is no error ,and will send an error string when there is an error ?
For SOAP: That is what faults are used for
SOAP faults are used to carry error information within a SOAP message. The fault is for SOAP what an exception is for a programming language.
When your client's request succeeds, you send back a valid response with the Employee structure, when it fails, you send back a fault with details of what went wrong.
For REST: Use HTTP Error Codes
Unlike SOAP, REST web services do not have a convention for returning errors but the simplest is to use the ones everybody understands.
For example you might send a HTTP 404 Not Found when a record is missing, a HTTP 500 Server Error when something happend on the database etc, and return HTTP 200 OK with your result when everything is fine and dandy.

HTTP status code for "success with errors"?

I've poked around a bit, but I don't see an HTTP status code for when a request's succeeds, but there is an error after the "point of no return".
e.g., Say you process a request, its committed to the database, but while returning the result you run of memory, or encounter a NPE, or what have you. It would have been a 200 response, but now, internally, you aren't able to return the proper, well-formed response.
202 Accepted doesn't seem to fit since we've already processed the request.
What status code means "Success, but errors"? Does one even exist?
HTTP doesn't have such a status code, but there is a best practice that allows you to handle such situations - redirect the user after a POST operation.
Here is a break down -
A POST request tries to modify data on the server
If the server fails, it sends a 500 error to indicate failure
If the server succeeds, it sends a 302 redirect response
The browser then sends a fresh GET request to the server
If this fails, you get a 500 error, otherwise you get a 200
So, your use case of 'Saved data but can't retrieve it immediately' translates to a 302 redirect for the initial POST, followed by a 500 for the subsequent GET.
This approach has other advantages - you get rid of the annoying 'Are you sure you want to resubmit the data?' message. Also keeps your back/forward/refresh buttons usable.
If the server is aware that it has encountered a problem, it should normally return a 5xx error. The most generic one is the 500 Server Error, which the RFC 2616 defines as follows:
500 Internal Server Error
The server encountered an unexpected condition which prevented it
from fulfilling the request.
Then it's the client's responsibility to reattempt the request. If the previous request was partially committed, it's the server's (or the database's) responsibility to roll that back, or to handle the duplicate transaction appropriately.
I agree with #Daniel that the proper response is an HTTP 500 (server error). The web application has to be written to roll back the transaction when there is an error, not leave things half-finished.
One thing you can leverage in your web application is "idempotency". This is the property of a function (or operation) that you can repeat it as many times as you like with the same result. For instance if a read fails, the client can simply retry it until it succeeds. If a deletion appears to fail, the client can again retry and the server will treat the request as valid whether or not the resource being deleted is already gone. And if an update appears to fail, the client can retry that until it gets a successful return from the server. The REST approach to architecting web services makes heavy use of idempotency to make operations robust in the face of error.

Resources