In my application, while logging exceptions, I need to show user friendly and localized error messages to the clients.
ie: CustomerNotFoundException should display the following to end user.
Customer-001
Customer was not found
I hope it is clear so far. I have services for i18n and error messages.
My error messages microservis provides key value pairs of Language, ErrorId and Error Message:
ie:
Error: Customer -001; Message: Customer Not found; Language:en-US
My question is about designing this process:
Should I convert exceptions to error messages that can be displayed to clients in a middleware? if so how do i map exceptions to error messages?
Or Should I inject ErrorService or I18N service in to the exceptions to provide message etc to the client ?
or is there a better way?
Related
I am receiving a soap FAULT message through two way port and looks as below ,
<S:Fault xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Status</faultcode>
<faultstring>Exception occured: TransactionRolledback</faultstring>
</S:Fault>
Error i am receiving : Only object types of 'System.Exception' can be added to the ESB Fault Message using this function
I am using separate exception block in orchestration using BTS.soap_envelope_1__1.Fault but still it fails ,
I want to catch this is ESB Exception and send to ESB Portal.
Follow the steps provided on this thread answer to catch the soap fault. Also as suggested adding steps here
To get the SOAP Fault into your orchestration:
On the Send port in BizTalk:
a) WCF Adapter Properties, Messages tab: Propagate Fault Message = true
b) WCF Adapter Properties, Messages tab: Inbound message body: Either use "soap:Body" or use a path that extracts your message OR /*[local-name()='Fault'] to get the SOAP fault
c) "Enable routing for failed messages" - this has no impact on the SOAP Fault. So you probably want it set to true to handle real transmission errors (non SOAP faults).
On the Send port within your orchestration
Select the operation & then "New Fault Message"
Set the message name to SoapFault (or whatever)
Set the message type to be the referenced schema: BTS.soap_envelope_1__2.Fault. (If this was a SOAP 1.1 operation you would use BTS.soap_envelope_1__1.Fault).
In the Scope around your Send operation
Add new exception handler
Select "Exception Object Type" to the port-name.operation-name.SoapFault you created in step 2
Specify the object name, e.g. Fault
Fault is now the XML of the SOAP Fault & you can use XPath to get the Fault Reason and Message elements.
Now, if a SOAP Fault occurs, no "exception" is shown in the BizTalk tracked message events view - it just shows that your orchestration receives the SOAP fault message. But inside your orchestration the message is treated as an exception and your "SoapFault" exception handler is called. You get a "FaultReceiveException".
Notes
1) The BizTalk Send Port tranmission retries option does not take effect if a SOAP fault occurs, because this is no longer viewed as a transmission failure. This is unfortunate, since the SOAP fault might be occuring due to a temporary problem at the target service & on retry the request might work.
2) Because the SOAP fault is not viewed by BizTalk as an error, your orchestration needs to log the message if you want to use routing of failed messages
3) You still need an exception handler for XlangSoapException's (i.e. System.Web.Services.Protocols.SoapException) and/or general exceptions, since these still occur for transmission errors (target server down, etc)
Because of (3), you will probably still want to specify "Enable routing for failed messages" to prevent suspended messages from occuring.
In my example I just received the soap:Fault part of the message, but you can pick up the entire soap:Envelope if needed.
I know that we can use FaultException and FaultContract to catch these exception?
Is there any other way to (Except FaultException/FaultContract) catch specifically these two Exception (Transport and Communication)?
According to the Microsoft documentation, transport and communication errors are handled by the CommunicationException class.
Communication errors occur when a network is unavailable, a client
uses an incorrect address, or the service host is not listening for
incoming messages. Errors of this type are returned to the client as
CommunicationException or CommunicationException-derived classes.
The following provides a good overview of the three categories of WCF errors:
Communication Errors
Proxy/Channel Errors
Application Errors
https://learn.microsoft.com/en-us/dotnet/framework/wcf/wcf-error-handling
I am logging the connection status events with the wcf relay, and I'm seeing something like this in the logs.
1/26 06:47:12 ERROR Service Bus ConnectionStatus: 'Reconnecting' Event. [(null)][42]
LastError: System.ServiceModel.CommunicationException: Exception of type 'System.ServiceModel.CommunicationException' was thrown. ---> Microsoft.ServiceBus.Messaging.Amqp.AmqpException: An AMQP error occurred (condition='amqp:unauthorized-access').
--- End of inner exception stack trace ---
This exception doesn't show up in the list on this microsoft page, and the only other post I can find anywhere related to this error message is here. However, that post does not have any recent comments or a resolution or workaround for the issue. Also, the exception doesn't have any stacktrace, so how am I supposed to troubleshoot this error?
I guess as a follow-up, I would ask whether this is anything to actually worry about if the wcf connection is never faulting.
Apparently, the token that the relay keeps refreshing to stay active requires the time on the server to match the azure service that it is connecting with, and if not, this type of error will show up. We were able to fix it by correcting the server time.
There is an asp.net based backend, where I use wcf services to communicate with client, which is a WPF application. When the data comes back from server, and during deserialization, it throws a communication exception. Here is the exception:
Exception thrown: 'System.ServiceModel.CommunicationException' in mscorlib.dll
Additional information: Error in deserializing body of reply message for operation 'AutoImportGetProtokolls'. The input source is not correctly formatted.
Source: http://pastebin.com/ZtUxYNUm
Here is a photo about the exception: https://www.dropbox.com/s/5araq9oajhrhrty/communicationexception.png?dl=0
I have another application based on silverlight, and when I call the same service, the exception does not come. After I start the WPF application the exception comes every time for first service call, after that it comes "randomly" (I could not find any logic when)
What I have tried so far but did not help:
-I used a DTO (data transfare object) class instead of generated one by entity framework. (sp_AutoImport_GetProtokolls_Result)
-Deleted the "out ErrorCustomModel res" parameter from service.
-Many source in google said that I should take a look for webconfing, and increase the property value of readerquotas. Here is the relevant part of webconfig: pastebin.com/e4ZpQsMK
Thank you guys, every hint are welcome.
Best Regards,
Norbert
I want to catch all unhandled exceptions thrown in a remote object on the server and log them there before I translate them into some custom exception so that specific exceptions do not cross the client/server boundary.
I think I have to use a custom channel sync, but can anyone confirm this and/or have any other advice to give?
I would use the Microsoft Enterprise Library Exception Handling app block -- it lets you handle errors and convert specific types of exception to a different type of exception before rethrowing to the client.
After finding Eliyahu Baker's helpful blog post and reading chapter 12 of Rammer's Advanced .NET Remoting I wrote a custom channel sink that does what I want. This intercepts any exception and logs it locally before sending it on to the client.
Ideally, I'd like to log the exception and raise a more generic one for the client, but I haven't cracked that nut yet.