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?
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.
I have created few custom exception class
public class CreateNewUserWebException : Exception
{
public CreateNewUserWebException(string email): base(
string.Format("[{0}] - User could not be added.", email))
{
}
}
public class CreateNewUserEntityFrameworkException : System.Data.DataException
{
public CreateNewUserEntityFrameworkException(string email)
: base(
string.Format("[{0}] - User could not be added.", email))
{
}
}
and here is my controller code
try
{
var user = _createUserModule.CreateUser(model);
CookieManager.SetAuthenticationCookie(user, model.Email, rememberMe: false);
return RedirectToAction("Index", "Bugs");
}
catch (CreateNewUserEntityFrameworkException exception)
{
this.ModelState.AddModelError("", "Some error occured while registering you on our sytem. Please try again later.");
Elmah.ErrorSignal.FromCurrentContext().Raise(exception);
}
catch (CreateNewUserWebException exception)
{
this.ModelState.AddModelError("", "Some error occured while registering you on our sytem. Please try again later.");
Elmah.ErrorSignal.FromCurrentContext().Raise(exception);
}
catch(Exception exception)
{
this.ModelState.AddModelError("", "Some error occured while registering you on our sytem. Please try again later.");
Elmah.ErrorSignal.FromCurrentContext().Raise(exception);
}
I have purposely fully induced an primary key violation exception which is
but exception is not catched by my custom exception class. It is not caught by the last exception catch block.
I cannot understand why so. Can some one help me out on this please.
The part you've highlighted in the debugger is the inner exception. That isn't used by the CLR to determine which catch block to enter. The outer exception is just a DbUpdateException - which you haven't specified a particular catch block for.
Even the inner exception is just a DataException - it's not an instance of your custom exception.
You haven't shown any code which actually throws your exception - are you sure it's being used at all? What code have you written to tell EF to throw your exception rather than the exception it would otherwise throw?
(Given your comments, I'm not sure you quite understand exception handling. Creating a custom exception doesn't somehow let you catch an instance of that without it being thrown - something still has to throw an instance of that exception before it's any use.)
I want a better way to catch database error details.
I'm currently using :
try
{
dbconn.table.AddObject(newRow);
dbconn.SaveChanges();
}
catch (Exception ex)
{
Console.WriteLine("DB fail ID:" + Row.id);
}
many times I found the Exception ex can no give me details on how the exception happen.
I think these exception most likely to be the DB connection kind.
So is there a better way to catch this ?
You should also output the exception. Most of the time, it holds useful and detailed information (e.g. names of violated constraints). Try this:
try
{
dbconn.table.AddObject(newRow);
dbconn.SaveChanges();
}
catch (Exception ex)
{
Console.WriteLine("DB fail ID:" + Row.id);
Console.WriteLine(ex.ToString());
}
For full details, use the ToString() method, it will give you the stack trace as well, not only the error message.
Use Console.WriteLine(ex.GetType().FullName) (or put a breakpoint and run under a debugger) to see the actual exception type being thrown. Then visit MSDN to see its description and base classes. You need to decide which of the base classes provides you with the information needed by exposing such properties. Then use that class in your catch() expression.
For Entity Framework, you might end up with using EntityException and then checking the InnerException property for the SQL exception object that it wraps.
try
{
dbconn.table.AddObject(newRow);
dbconn.SaveChanges();
}
catch (EntityException ex)
{
Console.WriteLine("DB fail ID:" + Row.id + "; Error: " + ex.Message);
var sqlExc = ex.InnerException as SqlException;
if (sqlExc != null)
Console.WriteLine("SQL error code: " + sqlExc.Number);
}
Instead of Exception use SqlException.
SqlException give you more detail. it has a Number property that indicate type of error and you can use that Number in a switch case to give some related information to user.
In short, yes there is a better way to handle it. The 'how' of it is up to you.
Exception handling in C# goes from the most specific exception type to the least specific. Also, you aren't limited to using just one catch block. You can have many of them.
As an example:
try
{
// Perform some actions here.
}
catch (Exception exc) // This is the most generic exception type.
{
// Handle your exception here.
}
The above code is what you already have. To show an example of what you may want:
try
{
// Perform some actions here.
}
catch (SqlException sqlExc) // This is a more specific exception type.
{
// Handle your exception here.
}
catch (Exception exc) // This is the most generic exception type.
{
// Handle your exception here.
}
In Visual Studio, it is possible to see a list of (most) exceptions by pressing CTRL+ALT+E.
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) });
}
I'm a bit confused at how to add a message to an error logged programatically with ELMAH.
eg:
public ActionResult DoSomething(int id)
{
try { ... }
catch (Exception e)
{
// I want to include the 'id' param value here, and maybe some
// other stuff, but how?
ErrorSignal.FromCurrentContext().Raise(e);
}
}
It seems all Elmah can do is log the raw exception, how can I also log my own debug info?
You can throw a new Exception setting the original as the inner exception and ELMAH will log the messages for both:
catch(Exception e)
{
Exception ex = new Exception("ID = 1", e);
ErrorSignal.FromCurrentContext().Raise(ex);
}
will show
System.Exception: ID = 1 ---> System.NullReferenceException: Object reference not set to an instance of an object.
I found that I can also do something like:
Elmah.ErrorSignal.FromCurrentContext().Raise(new NotImplementedException("class FbCallback.Page_Load() Request.Url= " + Request.Url));
To log my own messages. Then in when I browse to
http://localhost:5050/elmah.axd
I see my messages as type NotImplementedException.
Not very pretty but works.