How to Handle Exception in Wcf Rest Service - c#

I have method where it takes some parameter and the response is in json format.
On success it will return int type value.
But if error occurs then rest service will throw exception where as the method which is implements the REST service must return int value.
internal static int AddCatalog(string name, Guid key, string userName)
{
using (var client = new HttpClient())
{
HttpResponseMessage response = client.PutAsync(AdminRestServiceUrl + "xml/updatecatalog?cid=" + null + "&name=" + name + "&key=" + key + "&uby=" + userName, null).Result;
response.EnsureSuccessStatusCode();
var cid= response.Content.ReadAsStringAsync().Result;
return Convert.ToInt32(cid);
}
}
How can I handle it effieciently, if service throws error?
if i do like this
if(response.IsSuccessStatusCode == HttpStatusCode.OK)
{
return convert.ToInt32(cid);
}
else
{
return ?? //how to handle error here as method must retun int type
}
Please suggest how should I pass the detailed error message to the clients in order to notify them the exact error occurred in the service.
Any kind of help/suggestion is greatly appreciated.

you can do possibly Make an "ErrorLogs" Class ,Keep "Status" Field in it , and the Error Exception in "Message" Field , if there occurs any error send status to failed
In both Cases return a Class Which has both Error Logs and and Integer Value, if there is error Return Integer as -1 and handle it on Client

Related

Reporting error string from controller to the angular client

I have a controller method from which I would like to return to my angular client some error condition when account object is null. I used exception below and it works, but is there a better way of reporting error string to the angular client then the below one.
[Authorize]
[HttpPost("get-schedule-from-pool/{id}")]
public ActionResult<AccountResponse> GetScheduleFromPool(int id, UpdateScheduleRequest scheduleReq)
{
// users can update their own account and admins can update any account
if (id != Account.Id && Account.Role != Role.Admin)
return Unauthorized(new { message = "Unauthorized" });
var account = _accountService.GetScheduleFromPool(id, scheduleReq);
if(account == null)
{
// Request.Body.
// return HttpError("Function :" + scheduleReq.UserFunction + " for date: " + scheduleReq.Date + " already taken");
throw new Exception("Sample exception.");
}
return Ok(account);
}
If you want to return a error message or error code to the client there's a few ways to do it.
Using StatusCode:
return StatusCode(StatusCodes.Status500InternalServerError,"Details");
or
return StatusCode(500,"Details")
Or using the default wrappers:
return Problem("Details");
Here a list of all error codes and what they mean.

Send message with actionresult

I need to return the server error from azure functions.
Now I implement the same using InternalServerErrorResult(). It only sends the error code and no response/message can be sent with this function.
How to implement an exception handler where the error code and message can be sent together using actionresult in azure functions
current implementation
catch (Exception ex)
{
log.LogInformation("An error occured {0}" + ex);
//json = new Response(ex.StackTrace, AppConstants.ErrorCodes.SystemException).SerializeToString();
return (ActionResult)new InternalServerErrorResult();
}
this returns with an empty response in postman with error 500
Note that this is from Microsoft.AspNetCore.Mvc namespace:
var result = new ObjectResult(new { error = "your error message here" })
{
StatusCode = 500
};
Based on configured formatters it will return serialized object to client.
For JSON (it's default) it will return following:
{ "error" : "your error message here" }
To send a message with the status code you can use return StatusCode(httpCode, message), which is an ObjectResult.
For example:
return StatusCode(500, "An error occurred");
You can also pass an object (example using HttpStatusCode enum):
return StatusCode((int)HttpStatusCode.InternalServerError, json);

How to get the exception from HttpResponseMessage in web API?

I'm trying to implement a custom error handling in web API,
and I need to get the exception from the returned HttpResponseMessage.
I've tried to get exception info by from:
response.Content.ReadAsAsync<HttpError>().Result
But I can't access the result object, I'm getting an exception when trying,
So I'm obviously doing it wrong.
Can't figure out how to do it,
Assistance would be appreciated.
Edit:
My client code is not relevant, it's simply a GET request, server code:
Controller action throws Exception:
if (condition == true)
{
var response = new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent("Some Exception Related Message"),
ReasonPhrase = "Some More Info"
};
throw new HttpResponseException(response);
}
SendAsync method of my implemented DelegatingHandler gets the response,
and this is where I want to get the callstack of the exception that was thrown in the controller action above.
errorDetails = new ResponseErrorDetailsFull
{
Message = "An error has occurred.",
ExceptionMessage = response.ReasonPhrase,
StackTrace = response.Content.ReadAsAsync<HttpError>().Result.StackTrace
};
Edit #2
Ok, So I found out that if I create a ExceptionFilterAttribute, and Override OnException(), use the attribute on my DelegatingHandler I'm able to access the exception as mentioned in the above code.
Can someone provide an explanation why this is working this way?
To get HttpError in the response content, your server side API code needs to have written an HttpError instance into the response stream.
Only then response.Content.ReadAsAsync<HttpError>().Result would yield that data.
normally, if a server side code throws an exception, the default behavior is an HTTP 500 (Internal Server Error) status code with nothing parseable in the response message.
In case of HTTP 400 (Bad Request) or other such non-500 (non-200) errors, it is customary to send back response data. (either Validation Errors etc.)
in that case, you may be able to read the data from the response.
in general for any error scenario, unless your server side API code is not writing a known type into the response, you cannot read it off the response on the caller side.
please post your server side and client side code, for us to help you further.
I found this blog with very good example:
http://nodogmablog.bryanhogan.net/2016/07/getting-web-api-exception-details-from-a-httpresponsemessage/
I adopted the code with some updates:
if ((int)response.StatusCode >= 400)
{
exceptionResponse = JsonConvert.DeserializeObject<ExceptionResponse>(LogRequisicao.CorpoResposta);
LogRequisicao.CorpoResposta = exceptionResponse.ToString() ;
if (exceptionResponse.InnerException != null)
LogRequisicao.CorpoResposta += "\r\n InnerException: " + exceptionResponse.ToString();
}
using object:
public class ExceptionResponse
{
public string Message { get; set; }
public string ExceptionMessage { get; set; }
public string ExceptionType { get; set; }
public string StackTrace { get; set; }
public ExceptionResponse InnerException { get; set; }
public override String ToString()
{
return "Message: " + Message + "\r\n "
+ "ExceptionMessage: " + ExceptionMessage + "\r\n "
+ "ExceptionType: " + ExceptionType + " \r\n "
+ "StackTrace: " + StackTrace + " \r\n ";
}
}

WCF Service. How to return HTTP 500 response

I have a WCF service which access the registry and return the value. I would like to return a HTTP 500 response in certain cases for e.g. when I get null values returned from the registry without any exception. Here is my code. Instead of returning "null" string I want to return HTTP 500 response.
private string baseKey = "SOFTWARE\\Action\\software\\Station";
public string GetCode()
{
string Code;
try
{
using (RegistryKey regKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32))
{
using (RegistryKey subKey = regKey.OpenSubKey(baseKey, false))
{
Code = (string)subKey.GetValue("Code");
};
};
return string.IsNullOrEmpty(Code) ? "null" : Code;
}
catch (Exception ex)
{
return "null";
}
}
how can I create this HTTP 500 response to return to the client?
Please help.
Dif you tried this ?
throw new WebFaultException<string>("Registry key not found", HttpStatusCode.InternalServerError);
If an exception bubbles-up to WCF, WCF will set the HTTP Status to 500 and return a Fault.
In other words, throw an exception to return a 500 response to the client.
You can inject a status code, like this:
WebOperationContext ctx = WebOperationContext.Current;
ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.InternalServerError;
Note: InternalServerError is the HttpStatusCode enumeration values that maps to HTTP 500.

How to return error message from Catch block. Right now empty is returned

My sample code of ApiKey validation is given below (I am using MVC4 web api RC):
public class ApiKeyFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext context)
{
//read api key from query string
string querystring = context.Request.RequestUri.Query;
string apikey = HttpUtility.ParseQueryString(querystring).Get("apikey");
//if no api key supplied, send out validation message
if (string.IsNullOrWhiteSpace(apikey))
{
var response = context.Request.CreateResponse(HttpStatusCode.Unauthorized, new Error { Message = "You can't use the API without the key." });
throw new HttpResponseException(response);
}
else
{
try
{
GetUser(decodedString); //error occurred here
}
catch (Exception)
{
var response = context.Request.CreateResponse(HttpStatusCode.Unauthorized, new Error { Message = "User with api key is not valid" });
throw new HttpResponseException(response);
}
}
}
}
Here problem is with Catch block statement. I Just wanted to send custom error message to user. But nothing is sent. It displays a blank screen
However, the statement below is working well and sends out the validation error message correctly:
if (string.IsNullOrWhiteSpace(apikey))
{
var response = context.Request.CreateResponse(HttpStatusCode.Unauthorized, new Error { Message = "You can't use the API without the key." });
throw new HttpResponseException(response);
}
Is there anything that i am doing wrong.
I was having the same issue in the exact same scenario. However, in this scenario, you need to return some content in your response to be shown and not really throw the exception. So based on this, I would change your code to the following:
catch (Exception)
{
var response = context.Request.CreateResponse(httpStatusCode.Unauthorized);
response.Content = new StringContent("User with api key is not valid");
context.Response = response;
}
So with this change you are now returning your response, with content that will displayed in place of the blank screen.

Categories