SoapHeaderException was unhandled when calling web service - c#

An exception occurs on line
ModifyProfileResp resp = BFGlobal.modifyProfile(req);
INTERNAL_ERROR, SoapHeaderException was unhandled
Error: System.Exception._COMPlusExceptionCode -532462766,
This code basically updates the users information on a web service through a call I made.
public ModifyProfileResp ModifyProfile(string n_homeTelephone)
{
try
{
// Get Login Resp
LoginResp loginResp = LoginToBetfair("username", "password");
// Make a BFGS instance
BFGlobal = new BFGlobalService();
// Set up the request in [req]
ModifyProfileReq req = new ModifyProfileReq();
req.header = new APIRequestHeader();
req.header.sessionToken = loginResp.header.sessionToken;
req.homeTelephone = n_homeTelephone;
// Set up the response in [resp]
// Here is where Im getting thrown an exception..
ModifyProfileResp resp = BFGlobal.modifyProfile(req); // <-- Here Im getting thrown an exception
// return [resp] - which is the response from the call
// Just trying to print out errror codes
string mec = resp.minorErrorCode.ToString();
string ec = resp.errorCode.ToString();
return resp;
}
catch (Exception)
{
throw;
}
Pretty straightforward, make the request header, call the response, pass in the req and I should get some data back, but I keep getting thrown a exception on this line.
Any ideas on how to go about this?

First,
don't do this:
catch (Exception)
{
throw;
}
It's pointless. If you don't have the catch the exception will automatically get thrown up a level, which is what you're doing with throw. Further, if you can't do something with the exception (like retry the request) you're probably better off letting the exception bubble up.
Second, try something like this:
catch (SoapHeaderException ex)
{
Debug.WriteLine(ex.Message);
}
This will catch the specific exception that you're dealing with. Further, set a breakpoint here on the Debug statement. You can then browse the details of the exception. You'll be able to see the stacktrace, inner exceptions and any other data that the thrower of the SoapHeaderException might want you to see.
This information can often be useful when you're debugging, for example, it could say "You forgot to initialize the flux capacitor."

You're seeing an exception from the remote web service.
SoapHeaderException Class
The exception that is thrown when an XML Web service method is called over SOAP and an exception occurs during processing of the SOAP header.
Likely you're not setting up your headers as the remote service requires. Try to acquire help from the remote side.
Try viewing the .InnerException for more details.

Related

Exception not caught when thrown by RESTSharp

I'm using RestSharp to communicate with a REST-Server and wrote a small wrapper function for the call
private T Get<T>(string restAdress) where T : new()
{
try
{
// throw new Exception(); // This one is caught
IRestClient restClient = new RestClient(settings.Value.HostToConnect).UseSerializer(new JsonNetSerializer()); // (1)
RestRequest restRequest = new RestRequest(restAdress);
IRestResponse<T> result = restClient.Get<T>(restRequest); // (2)
return result.Data;
}
catch (Exception e) // debugger wont stop here
{
// debugger wont stop here too
// code within this block is not executed
}
return null; // (3)
}
Since I want to use the Newtonsoft-Attributes I give in a custom (de)serializer (1).
public class JsonNetSerializer : IRestSerializer
{
public string Serialize(object obj) =>
JsonConvert.SerializeObject(obj);
public string Serialize(RestSharp.Parameter bodyParameter) =>
JsonConvert.SerializeObject(bodyParameter.Value);
public T Deserialize<T>(IRestResponse response) =>
JsonConvert.DeserializeObject<T>(response.Content); // (4)
public string[] SupportedContentTypes { get; } =
{
"application/json", "text/json", "text/x-json", "text/javascript", "*+json"
};
public string ContentType { get; set; } = "application/json";
public DataFormat DataFormat { get; } = DataFormat.Json;
}
When calling the REST service and trying to get the result (2) an Exception is thrown if the deserialization fails (4). But the Exception is not caught by the try-catch block. I tried to debug but after throwing the debugger goes on in line (3), the catch and the logging withing the catch is never executed. The debugger won't even stop at the catch (Exception e) it goes straight from (4) to (3).
(Sorry for not english, the title of the window says "Exception User-Unhandled")
Can anyone explain this behaviour to me?
Whats happening here is an interesting setting of the debugger, another example would be this closed bug report. When the debugger reaches the point the exception is thrown it will break, causing the behaviour you experienced.
If you uncheck the exception setting "Break when this exception type is user-unhandled" in the dialog, you should be able to reach your catch block, as the debugger no longer breaks the execution as soon as the specified exception is thrown.
In your case you find that option under "Ausnahmeeinstellungen".
I am maintaining RestSharp, so I hope I can answer this.
RestSharp doesn't throw on deserialisation by default. If you look at the code, deserialisation happens in the private IRestResponse<T> Deserialize<T>(IRestRequest request, IRestResponse raw) method of RestClient.
When RestSharp can't deserialise the response, it creates an error response. You get the response status set to Error and the exception is put into the ErrorException property of the response object, along with the exception message that gets to the ErrorMessage of the response.
It is still possible to tell RestSharp to throw on deserialisation if you assign the FailOnDeserialization property of the RestClient instance to true.

Best Practice in OData for exceptions

We are consuming OData service using dot-net.
When any exception throws in the odata service code or any business logic problem fails, service code handles that exception or error and return dotnet consumer a new error object with that error details.
Is it good way of doing as I am thinking it should throw an exception and at consuming end I should handle it in my own way.
What are your suggestions ?
Both are OK. In both cases you need a specific manner to transfer the service status and error info:
// First case - the returned object contains status and error info.
IResponse response = OData.Serve();
if (response.Status == Status.Ok)
ManageResponse(response );
else
ManageError(response.Status, response.Error);
// Second case - service rises an exception.
IResponse response;
try
{
response = OData.Serve();
ManageResponse(response);
}
catch (ODataException e)
{
ManageError(e.Status, e.Error);
}
// Third case: Service returns correct response or null.
// In case of error Service contains error info.
IResponse response = OData.Serve();
if (response != null)
ManageResponse(response);
else
ManageError(OData.LastError);
You can also try something like this also :
try
{
//your Odata query and response code
}
catch (DataServiceClientException dsce)
{
logger.WarnFormat("Client Exception, Status Code - {0}", dsce.StatusCode.ToString());
}
catch (DataServiceRequestException dsre)
{
logger.WarnFormat("Request Exception - {0}", dsre.Message);
}
catch (DataServiceQueryException dsqe)
{
logger.WarnFormat("Query Exception, Status code - {0}", dsqe.Response.StatusCode.ToString());
}
Hope it helps :)

How to catch a web service exception

How do you catch exceptions from a Web Service that is returning a custom object?
I've seen this post but it doesn't seem to show how to get the exception that was thrown by the service.
I can pull the SOAP Exception, but I want to be able to get the original exception that the web service returned. I've looked at the variables that are set at this time and can't seem to see the exception anywhere, I just see:
"Server was unable to process request. ---> Exception of type
'RestoreCommon.ConsignmentNotFoundException' was thrown."
try
{
Consignment cons = WebServiceRequest.Instance.Service
.getConsignmentDetails(txtConsignmentNumber.Text);
lblReceiverName.Text = cons.Receiver.Name;
}
catch (ConsignmentNotFoundException)
{
MessageBox.Show("Consignment could not be found!");
}
Is this possible?
In short, no.
Web services will always throw SOAP fault. In your code,
MessageBox meant to be used in Windows forms and nowhere else.
You can throw this exception and in the client application, you will have to handle a SOAP fault.
Edit: If you do not want to send exceptions across to the client, this what you could do:
class BaseResponse
{
public bool HasErrors
{
get;
set;
}
public Collection<String> Errors
{
get;
set;
}
}
Each WebMethod response must inherit from this class. Now, this is how your WebMethod blocks would look like:
public ConcreteResponse SomeWebMethod()
{
ConcreteResponse response = new ConcreteResponse();
try
{
// Processing here
}
catch (Exception exception)
{
// Log the actual exception details somewhere
// Replace the exception with user friendly message
response.HasErrors = true;
response.Errors = new Collection<string>();
response.Errors[0] = exception.Message;
}
finally
{
// Clean ups here
}
return response;
}
This is just an example. You may need to write proper exception handling code rather than simply using generic catch block.
Note: This will take care of exceptions occurring in your application only. Any exceptions occurring during communication between client and service, will still be thrown to the client application.

Verbose exception with service operation

I'm using C# to build a service operation. When something goes wrong, I want to throw an exception that could be catch client side.
However, when an exception is thrown the client is only able to get a generic error like "400: bad request" and the exception message is not accessible.
In my service operation, I have enabled verbose errors with this:
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
and
config.useVerboseErrors = true;
I also unpack the TargetInvocationException and instead return a DataServiceException with this function:
protected override void HandleException(HandleExceptionArgs args)
{
// Handle exceptions raised in service operations.
if (args.Exception.GetType() == typeof(TargetInvocationException)
&& args.Exception.InnerException != null)
{
if (args.Exception.InnerException.GetType() == typeof(DataServiceException))
{
// Unpack the DataServiceException.
args.UseVerboseErrors = true;
args.Exception = args.Exception.InnerException as DataServiceException;
}
else
{
// Return a new DataServiceException as "400: bad request."
args.UseVerboseErrors = true;
args.Exception = new DataServiceException(400, args.Exception.InnerException.Message);
}
}
}
When I use the browser, I can see the verbose exception message, but when I try programmatically, the inner exception is null and I only see the generic error message "400: bad request".
Strangely, if I return a code 200 instead of 400, I can see the exception message in the answer body. But obviously I don't want to do this.
So, is there a way to get the exception message client side, when you throw an exception from a service operation?
Have you had a look at end to end tracing? Furthermore, this MSDN page isn't as daunting as it may first seem, and i think the "Provide Additional Information When an Exception Occurs" section would be useful to you. Have a lovely read.

Exception handling issue in C#

I am currently trying to add an exception handler on some code. That code simply creates an instance.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(firstline);
I have tried:
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(firstline);
}
catch(Exception ex)
{
// code here
}
I get the following compilation error:
Error 1 The name 'request' does not exist in the current context.
By adding the try on to the statement. Am I missing something?
The chances are that the exception is happening not when you try to create the request, but when you try to get the response:
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (Exception ex)
{
// Handle exception here
}
When using try-catch blocks you need to surround the line of code that fails. (You probably need to read the documentation some more).
Bear in mind when using try-catch blocks that anything that you intend to use outside of the try block needs to be scoped accordingly (delcare it outside of the try block, as I have done above).
It seems that you're trying to use your "request" variable outside of the try block.
You need to declare it outside of the block if you want to use it after the try/catch block.
HttpWebRequest request;
try
{
request = (HttpWebRequest)WebRequest.Create(firstline);
}
catch (Exception ex)
{
}
// Your request variable won't be destroyed now, you can use it here
I think what your looking for is;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(firstline);
HttpWebResponse HttpWResp = (HttpWebResponse)HttpWReq.GetResponse
if(HttpWResp.StatusCode ==200)
{
//Sucessfull code
}
else
{
//fail code
}
}
catch(Exception ex)
{
// Exception codee here
}
I guess that that the exception is not thown in the line that you think. Try to add an Application level exception handler. And then, use Environment.StackTrace to track the line the application failed on.
If you're using Visual Studio, use Debug exceptions and check Thrown for Common Language Runtime exceptions.
Hope it helps.

Categories