I have a scenario in one of my Service Broker conversation configurations, which looks like this:
one message type, which is sent by initiator only (VALIDATION = WELL_FORMED_XML, no XSD)
one contract with this message type
both deployed on the initiator and target side (remote machines)
Occasionally I find Service Broker system error messages in the target queue like this:
<Error xmlns="http://schemas.microsoft.com/SQL/ServiceBroker/Error"><Code>-9616</Code><Description>A message of type 'here_is_the_name' was received and failed XML validation. XML parsing: line 1, character 547, illegal xml character This occurred in the message with Conversation ID 'here_is_the_guid', Initiator: 1, and Message sequence number: 0.</Description</Error>
I looked at Remus Rusanu's blog post and he states that:
This system error is sent to a conversation that has sent a message type marked as conforming to a certain XML schema but the payload has failed to pass the XML validation for the said schema
In my case there is no XML schema involved and I was trying to reproduce this case in my dev env using the same SQL Server versions and I was unable to do it.
I would like to know is it possible to receive this system error message although I'm not using XSD schema ? If so, when can it happen, what is the scenario where Service Broker generates error like above?
The message clearly says "XML parsing: line 1, character 547, illegal xml character" so in my opinion it has nothing to do with the schema validation.
Can it be that the transport level is encountering some problems (TCP errors) and that is why Service Broker is generating this error message ?
Message validation occurs on enqueue the message in the target queue, not on SEND. Message type validation (NONE, XML, XDS) is provided to protect your application. Validating during SEND is not enough, as a malicious application can send a message w/o using Service Broker ( a wire protocol simulator). Since validation during enqueue is mandatory, adding validation during SEND would add CPU burden for little value.
So what that means is the your SEND side application is sending invalid XML, and this gets caught on the target side. The wording on my blog is poorly chosen, I should had been more explicit that the validation can fail a schema (if specified) or it can fail the well formed XML test.
Can you post the message body you're sending?
Related
Here is an image of a common structure we have in a few of our BizTalk orchestrations:
So when we GET information from an API and the account doesn't exist, we terminate the orchestration. This works fine and I can see the orchestration doing this and terminating when it should, but what I don't understand is why do I see the suspended message from the GET in the console? Since the exception handling works, shouldn't this stop an error showing in the console?
As a way around this, I've considered using a pipeline component to check the response message, and if it contains what would be ignored, just return null in place of the message. Would this have the desired effect? I'm more interested as to why I see the suspended messages in the console.
Yes, this is a known issue with the WCF-WebHttp adapter, that has to do with the fact that it throws it back as a SOAP formatted error, but without setting the MessageType context property (see my blog post and look for Bug: BizTalk WCF-WebHttp adapter does not set the message type on error). So although the exception is thrown back at the Orchestration and can be handled there, the message is not as BizTalk does not know what type it is and it suspends.
A workaround we use is
To set Enable Routing for failed messages on the send port
To have a send port that subscribes to all the response messages from that send port using the BTS.SPName = xxxx filter, and send port sends it to a custom NULL adapter (throw the message away), and yes, your Orchestration will still get the good response as well as the exceptions.
Update the send port that handles routing errors from other send ports that we do want to go to our exception handing to exclude those send ports which we are handling via an Orchestration.
I am using IBM integration toolkit
I have an application with two flows; the request flow has a json request message using http request node then the message is thrown to another flow (in another application representing a stub)through a MQ Input, compute node then MQ reply.
It then throws the message to the response flow in my application through MQ Input
I need to output the message in a json form through http reply node but in the flow it runs an exception "Message does not contain valid HTTP context information, Need return context info"
if anyone have a clue for this error and how to solve it
Thanks in advance
The problem is that your HTTP response flow does not know which request it has to respond.
In case you really need your request and response to be implemented as different flows, you have to store identifier of incoming HTTP or SOAP request somewhere, for example as a message in some dedicated queue.
In your request flow you can find identifier of request in
InputLocalEnvironment.Destination.HTTP.RequestIdentifier
or
InputLocalEnvironment.Destination.SOAP.RequestIdentifier
depending on the type of your input node.
Then, your response flow should read a message written by request flow to find a value of RequestIdentifier.
This value should be set into the LocalEnvironment of response message assembly:
OutputLocalEnvironment.Destination.HTTP.Reply.ReplyIdentifier
or
OutputLocalEnvironment.Destination.SOAP.Reply.ReplyIdentifier
Here is IBM doc: https://www.ibm.com/support/knowledgecenter/SSMKHH_9.0.0/com.ibm.etools.mft.doc/ac20450_.htm#ac20450___le
When the HTTPInput node receives an input request message, it sets the local environment field Destination.HTTP.RequestIdentifier to a unique value that identifies the Web service client that sent the request. You can refer to this value, and you can save it to another location if appropriate.
For example, if you design a pair of message flows that interact with
an existing WebSphere MQ application (as described in Broker calls
existing Web service), you can save the identifier value in the
request flow, and restore it in the reply flow, to ensure that the
correct client receives the reply. If you use this technique, you must
not change the data, and you must retain the data as a BLOB.
The HTTPReply node extracts the identifier value from the local
environment tree and sets up the reply so that it is sent to the
specific client. However, if you are using an HTTPReply node in a flow
that does not have an HTTPInput node, and this field has been deleted
or set incorrectly, message BIP3143S is issued.
In a classic form-based webapp, if a user submits a HTML form that contains validation errors, assuming no JavaScript, what's the correct thing to do?
Respond with the HTTP 200 + the page content (including error info for the user)
Respond with the HTTP 400 + the page content (including error info for the user)
Does it matter?
Your app is talking to human beings, not other machines. Therefore you should do the right thing and handle exceptions in a user-friendly manner.
Your user doesn't care about HTTP return codes, and so it should not even be a consideration for you either. You are confusing business-logic problems with HTTP protocol problems.
Infact, by throwing a 400 error at a web-browser, you are only likely to encounter the web browser throwing up an ugly message to the user.
If you were coding a REST api, then the answer would be different. But you're not.
1) would be the correct approach because you want to display a page of content to the user that highlights the invalid input values.
The trouble with 2) is that some browsers may display their own 'friendly' error page that is designed to help users understand 4xx errors. Here's some information about when IE displays 'friendly' error pages:
http://support.microsoft.com/kb/294807
On the one hand, if it is a web app for human consumption, a 200 with a some useful error message will work. Making web sites for humans is easier in that sense because they can read and understand the content and do not have to depend on the status code for interact with the applications.
On the other hand, If you thinking of a REST API more appropriate would be to throw a 4xx error because it is a client side error. In that case, you have several options.
According RFC2616, a 400 means
The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without
modifications.
This doesn't seem to be appropriate as it's not due to malformed syntax.
However, RFC2616 is now obsoleted by RFC7230-7235. The new RFC7231 defines the meaning of 400 in a more broader way.
Client Error 4xx The 4xx (Client Error) class of status code indicates
that the client seems to have erred. Except when responding to a HEAD
request, the server SHOULD send a representation containing an
explanation of the error situation, and whether it is a temporary or
permanent condition.
400 Bad Request
The 400 (Bad Request) status code indicates that the server cannot or
will not process the request due to something that is perceived to be
a client error (e.g., malformed request syntax, invalid request
message framing, or deceptive request routing)
So this seems acceptable even though still generic. Another option would be to use 422 status code defined by RFC4918 (WebDAV).
422 Unprocessable Entity The 422 (Unprocessable Entity) status code
means the server understands the content type of the request entity
(hence a 415(Unsupported Media Type) status code is inappropriate),
and the syntax of the request entity is correct (thus a 400 (Bad
Request) status code is inappropriate) but was unable to process the
contained instructions. For example, this error condition may occur
if an XML request body contains well-formed (i.e., syntactically
correct), but semantically erroneous, XML instructions.
When I read a message with a WSO2 ESB Proxy, I need to define a specific datatype and this is then applying a certain MessageBuilder (defined in the axis2.xml).
But when the MessageBuilder fails (i.e. I try to read a text file with the XMLBuilder) I get an exception in the console, but my "faultSequence" is not called. But I need to do a certain Error Handling in case of any read problem.
How can I catch Exceptions from the Transport Layer (MessageBuilder) in a Proxy?
As far as i understand , your requirement is to catch an Error in the Transport layer and handle that in the Application level (i.e : Mediation level). which means the layer above.
But i think it violates layered architecture of the messaging framework. You should catch the Exception at the Message Builder itself and throw an Axis Fault so that underlying synapse transport layer (in this case Axis2) will handle that error. (It will send a fault to the client.)
If we look at the TCP protocol stack that is the practice which is commonly used.
If you really want to filter this errors at mediation level. Catch that Error in the Message Builder and add a Message Context property or custom message and pass it as a successful message. And Do a filter in mediation level and handle.
But again that is ugly.
:)
--Charith
Have you defined onError attribute in your configuration?
<sequence name="main" onError="myFaultSequence">
You can have more information in this sample.
I have a email multi-part message which I am using to send failed message routing from the messagebox to a business users mailbox.
Email{ Body - RawString; OriginalMessage - string};
The original message gets set from the received message that activates the orchestration. For example assume the original failed message is from a Flat file that failed disassembly with the contents:
Order,1,2,3,4,5,<6>,
I set the message using:
Email.OriginalMessage = MyUtil.XlangMsgToStringMethod(FailedMessage);// XmlDocument type, this can be malformed xml, valid xml, or flat file that fails in disassembler.
I can then write to the event log to test whats in Email.OriginalMessage:
System.Diagnostics.EventLog.WriteEntry("BizTalk Server 2006", Email.OriginalMessage, Information); // This displays the correct original message "Order, 1,2,3,4,5,<6>,"
When the email is delivered using a SMTP server and a dynamic send port, with the attachment set to text/plain mime type, the original message gets xml encoding escaped and wrapped in xml:
<?xml version="1.0"?>
<string>Order, 1,2,3,4,5,<6>,</string>
Any ideas why? The SMTP port has passthrutransmit as pipeline.
Thanks.
SMTP port is getting XMLTransmit forcing the message to be treated as XML.
Switch to PassThroughTransmit.