Is there anyway we can get HttpStatus code when exception caught? Exceptions could be Bad Request, 408 Request Timeout,419 Authentication Timeout? How to handle this in exception block?
catch (Exception exception)
{
techDisciplines = new TechDisciplines { Status = "Error", Error = exception.Message };
return this.Request.CreateResponse<TechDisciplines>(
HttpStatusCode.BadRequest, techDisciplines);
}
I notice that you're catching a generic Exception. You'd need to catch a more specific exception to get at its unique properties. In this case, try catching HttpException and examining its status code property.
However, if you are authoring a service, you may want to use Request.CreateResponse instead to report error conditions.
http://www.asp.net/web-api/overview/web-api-routing-and-actions/exception-handling has more information
I fell into the same trap when doing error handling in my WebAPI controllers. I did some research on best practices for exception handling and finally ended up with following stuff that works like a charm (hope it will will help :)
try
{
// if (something bad happens in my code)
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent("custom error message here") });
}
catch (HttpResponseException)
{
// just rethrows exception to API caller
throw;
}
catch (Exception x)
{
// casts and formats general exceptions HttpResponseException so that it behaves like true Http error response with general status code 500 InternalServerError
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError) { Content = new StringContent(x.Message) });
}
Related
When the HttpClient throws an exception trying to get a page it returns a HttpRequestException. This exception doesn't really have anything to categorize the error apart from the message so the only way i can see to handle errors is like so:
try
{
HttpResponseMessage response = await client.GetAsync("http://www.example.com/");
// ...
}
catch (HttpRequestException e)
{
if(e.Message == "Name or service not known")
{
HandleNotKnown();
return;
}
if(e.Message == "Some other specific message")
{
HandleOtherError();
return;
}
// ... etc
}
I don't like doing this because I feel like at some point the error text could change in an update and break my code.
Is there a better way to handle specific errors with HttpClient?
The HttpRequestException inherits from Exception and so it has the InnerException property
Gets the Exception instance that caused the current exception.
So check this Exception for more details.
Can I catch the exception that appears in the log but not in the test?
I performed the test and it returned the status: OK, but in the log I have:
Unexpected error publishing create package to Kafka. id = 5ec3eb81aa662c8a7c76e5e8. Exception: System.NullReferenceException: Object reference not set to an instance of an object.
How can I catch this exception in the test? I tried to use Try and catch (Exception) but nothing catches.
[Fact]
[DisplayTestMethodName]
public async Task ExceptionTest()
{
try
{
var testRequest= #"{""Test1"":"1234"};
var testRequestResp =
await fixture.PostAsync(testRequest);
Assert.Equal("HttpStatusCode: " + System.Net.HttpStatusCode.OK, "HttpStatusCode: " + testRequestResp.StatusCode);
}
catch (Exception ex)
{
Assert.True(ex == null, "Exception: " + ex.Message);
}
Log
VS log
This means you are handling the NullReferenceException already somewhere in your PostAsync method and still returning status 200. That is a design decision to swallow the error and return "OK" (hopefully you are logging it or something at least).
A different approach would be to return a 500 status instead of 200, to indicate that an internal server error has occurred - then try and address the NullReferenceException.
You may also choose not to swallow the error in you PostAsync method and let it bubble all the way up. In that case, you could use:
var exception = await Assert.ThrowsAsync<NullReferenceException>(() => fixture.PostAsync(testRequest));
(Where testRequest was something you knew would trigger that error)
If getting a NullReferenceException is expected behavior and the request is still "OK" status, then somehow catching it in your test would make no sense.
I want to check that the exception "NullReferenceException" does not occur.
I used your advice:
var exception = await Assert.ThrowsAsync<NullReferenceException>(() => fixture.PostAsync(testRequest));
But I don't catch this exception
Where is the problem?
I have a code segment that is responsible for orchestrating the execution of a few modules and it is very sensitive to errors - I want to make sure I log and alert about every exception that occurs.
Right now I have something like this:
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
}
catch (Exception ex)
{
string errorMessage = string.Format("Module A failed doing it's thing. Specific exception: {0}", ex.Message);
// Log exception, send alerts, etc.
}
try
{
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
string errorMessage = string.Format("Module B failed doing it's thing. Specific exception: {0}", ex.Message);
// Log exception, send alerts, etc.
}
// etc for other modules.
It looks to me that the multiple try-catch is making this segment less readable. Is it indeed the right thing to do?
Yes, it's the right thing.
But you should have the performance in in mind, maybe it's better to put all method calls in one try/catch and add stack trace and error information in the exception in the methiod itself.
public void ModuleA.DoSomethingA()
{
throw new Exception("Error in module A");
}
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
// get information about exception in the error message
}
You did well.
This way, you can process the error after each module. If you want to run it all and then do error handling, consider this alternative:
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch(ModuleAException ex)
{
// handle specific error
}
catch(ModuleBException ex)
{
// handle other specific error
}
catch (Exception ex)
{
// handle all other errors, do logging, etc.
}
i think that depends on the approach that you want to follow.
It seems like you error messsages are different for each module that raises exception so i guess the approach that you followed is right.
you could have put the whole thing in a big try - catch block then in that case you will not know which module caused the exception as a generic excpetion gets printed.
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
string errorMessage = string.Format("Either Module A or B failed", ex.Message);
// Log exception, send alerts, etc.
}
So if you want your exception handling to not be cleaner use the above code.
Otherwise what you followed is absolutely fine.
I am working with WebApi and ELMAH and I would like to be able to wrap some business errors into web responses for some thypes of exceptions(no logging) and have the others logged by ELMAH. Right no I have this piece of code.
public async override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
{
try
{
return await base.ExecuteAsync(controllerContext, cancellationToken);
}
catch (MyException ex)
{
return new HttpResponseMessage(CustomCode)
{
Content = new StringContent(CustomMessage)
};
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
return new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent("Ups! Something went wrong. Please try again or contact administrator!")
};
}
}
The problem is I would expect ELMAH to log only unhandled exceptions. In my case, even the exception of type MyException is being logged, although it is caught by the catch block.
Is there any config I can apply to ELMAH to make it log only unhandled eceptions ?
ELMAH catches all exceptions thrown from your web app. If you want to filter out certain errors, you could the error filtering feature of ELMAH as described here:
https://code.google.com/p/elmah/wiki/ErrorFiltering
In your case you would probably need to add something like this to your global.asax.cs:
void ErrorMail_Filtering(object sender, ExceptionFilterEventArgs e)
{
if (e.Exception.GetBaseException() is MyException)
e.Dismiss();
}
I am trying to figure out how to return exceptions and errors up to the controller level from my repository and be able to return custom errors to the client when they call my web service.
I have the following example from my BookRepository class:
public BookViewModel GetBookById(Guid id)
{
var Book = _Books.Collection.Find(Query.EQ("_id", id)).Single();
return Book;
}
obviously my function would be a little more complicated than this, but if i called this method on a id that did not exist i would get an exception. How can I have my exceptions and custom errors bubble up to my controller and then displayed nicely in the client response
Even a web service should follow the same patterns as any other code, with respect to exception handling. Those best practices include not using custom exceptions unless the caller is going to make a programmatic choice based on the exception type. So,
public BookViewModel GetBookById(Guid id)
{
try
{
var Book = _Books.Collection.Find(Query.EQ("_id", id)).Single();
return Book;
}
catch (SpecificExceptionType1 ex)
{
Log.Write(ex);
throw new Exception("Some nicer message for the users to read", ex);
}
catch (SpecificExceptionType2 ex)
{
Log.Write(ex);
throw new Exception("Some nicer message for the users to read", ex);
}
catch (Exception ex)
{
Log.Write(ex);
throw; // No new exception since we have no clue what went wrong
}
}
what edmastermind29 mentioned is one common way to do it. i would usually the same way.
but sometimes developers like to catch the exception before the controller and return a result message based on enumerated value for example , so the controller would have no try catch blocks for that call, it will only need to check the status message.
you can use out parameter to check status and display messages for users accordingly.
this is how ASP.NET Membership provider is implemented.
check the method create user in Membership provider for example:
http://msdn.microsoft.com/en-us/library/system.web.security.membershipprovider.createuser(v=vs.100).aspx
Place a try-catch around methods, LINQ queries, etc. that may fail given a circumstance (null value, empty value, invalid value, etc.). From there, you can catch the exception, and throw a custom exception tailored to what you are looking for. See below.
public BookViewModel GetBookById(Guid id)
{
try
{
var Book = _Books.Collection.Find(Query.EQ("_id", id)).Single();
return Book;
}
catch (Exception e)
{
Log.Write(e)
status = "Some Custom Message";
}
catch (DoesNotExistException dne)
{
Log.Write(dne)
status = "Some Custom Message about DNE";
}
}