Http 500 in IIS Log when i throw a c# exception - c#

Is there any possibility to throw an exception in the code of a web application which would not cause error 500 in the IIS logs?

500 means internal server error, i.e. your application have failed.
I'm guessing that you are asking for some sort of indication when the client have done something wrong.
For MVC 5.x there is an HttpException which can be used to return other error codes. (500 is returned for all exceptions but HttpException)
However! Exceptions are application failures. Your application does not fail just because the client sent something invalid.
Instead, you should send back a HttpResponse with the correct HTTP code. For MVC applications you can use the HttpStatusCodeResult in the controller.

Related

Is there a way to change the HTML Error Code, if the permitted URL is too long?

We got the following problem:
I am currently developing a web server implementing a specific API. The association behind that API provided specific test cases I'm using to test my implementation.
One of the test cases is:
5.3.2.12 Robustness, large resource ID
This test confirms correct error handling when sending a HTTP request with a very long location ID as URL parameter.
The url its calling looks something like this:
https://localhost:443/api/v2/functions/be13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005ebe13789-1f1e-47d0-8f8a-000000000005
Basically the tests checks, if my server responds with the correct error code if the URL is too long. (At the time of writing it is testing for Errorcode 405, but I already asked them if it shouldn't be 414)
I'm developing the server in Asp.Net 6 and it always returns Bad Request 400 in the testcase.
I don't seem to find a place to change the handling for this behaviour and I am not even sure, if I can, or if the IIS is blocking the request even before it reaches my server. I activated logging in IIS, but the request does not show in the logfile in inetpub/logs/LogFiles.
My question would be, if it is possible to tell IIS to return a different error code in this case, or if it is even possible to handle the error in my application.
What I tried:
Activating IIS Logs to see if the request is even passed to my site. (It did not)
Tried adding Filters to my Controller to see if I can catch an Exception
Checked, if Development Error Sites are called.
Breakpoints in existing middlewares are not reached.
EDIT:
I am now pretty sure now, that the request never reaches my application.
It is possible to reproduce the error by using the default site the IIS generates on windows. Just copy the whole path from above into a browser with the host http://localhost will also just produce the error 400
EDIT 2:
As #YurongDai pointed out, I tried activating failed request tracing for my IIS Site. I used the default path \logs\FailedReqLogFiles.
The folder was created, but no file is written, when I'm opening the URL above in my browser.
IIS Error 400 occurs when the server is unable to process a request sent to a web server. The most common cause of Bad Request error 400 is an invalid URL, but it can happen for other reasons as well. To resolve IIS Error 400, first make sure that you have entered the URL correctly, typos or disallowed characters in the URL are the most common causes of Bad Request errors. If the error persists after verifying the URL, please clear your browser's cache, DNS cache, and cookies and try again.
Clear your browser's cookies.
Clear your browser's cache.
Clear your DNS cache.(Execute the following command in the command prompt window: ipconfig /flushdns)

WebRequest and Node.js - error handling

What would be the correct way of handling errors in communication between a C# client app and Node.js server? My solution was to send status code 400 or 500 and error message in the response body, but WebRequest seems to not receive the body message when status code implies an error. I need to read this error message to show for the user the correct info about the error.
I guess typically server would throw WebRequestException which could pass the error message, however I have no idea how to throw such error from the Node.js app.
I cannot change the status code to 200 and read error from the body because previous versions of the app would not handle it correctly.
Well, I figured it out. In the client, in the catch block, when WebRequestException is thrown because of the error status code, you can still begin receiving the response (the response is in this exception).
My bad. :)

Return custom errors WebApi ASP.NET 5 HttpResponseException wrong status code

WebAPI / REST allows you to send custom error messages together with a standard Status Code, i.e. 402 - Not found + your own message in the header / body.
This works great on ASP.NET 4.X, but with ASP.NET 5 RC 1 there's something amiss.
While my code to throw custom errors looks something like this:
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Ambiguous)
{
Content = feedback, ReasonPhrase = reason }
);
The code returned (to Angular) isn't the code specified (300 in the example).
On localhost / IIS Express i get 500 Internal Server Error and in production on Azure I get 404 Not Found.
Looking at the ASP.NET docs I see something that might be relevant:
If the server catches an exception before the headers have been sent
it will send a 500 Internal Server Error response with no body.
https://docs.asp.net/en/latest/fundamentals/error-handling.html#server-exception-handling
So has anyone successfully returned status codes with custom (body) messages to client from ASP.NET 5 RC 1 WebAPI?
UPDATE:
This methodology seems to work better - but that doesn't answer why HttpResponseException doesn't work.
this.Response.StatusCode = (int)HttpStatusCode.BadRequest;
return this.HttpBadRequest(new { ex.Message });
To answer your updated question, they removed that use of HttpResponseException because it encouraged the bad practice of using exceptions for flow control. See https://github.com/aspnet/Mvc/issues/4311.

Why HttpRequestValidationException has 500 http error code instead of 400?

When I tested my web-app based on MVC5 I found that HttpRequestValidationException returns 500 from GetHttpCode().
I catch this exception during security testing of requests to the server. MVC performs request validation and throws this exception, I processed it in the Application_Error and got 500 code returned, but, in fact, if user passed wrong input to server I should return 400 error (bad request). so don't understand why the exception has 500 error. Where I am wrong ?
There are four reasons why 500 might be considered more appropriate.
One is that it isn't clear when a HttpRequestValidationException happens who did the wrong thing. It could be that the user quite clearly sent something incorrect, but it's also possible that the server incorrectly rejected something that was perfectly fine. Considering that this is the default behaviour on many requests that could be malicious, it's probable that the majority of cases where its thrown in response to non-malicious requests (the user isn't actively trying to do the site harm) fall into this category. Hence it could either be something that should be consider 4xx or 5xx and 5xx is a good assumption (don't blame the client when you aren't sure it's the client's fault).
When it happens in a non-malicious case it generally needs attention from a developer, which is only sometimes true of the 4xx codes (a 404 might need developer-attention because the 404 was caused by a bad link on the same site, but it might not). The sort of feedback one gets from 500 responses is more appropriate.
The general model ASP.NET started with pretty much mapped all exceptions to 500 responses, which does make sense a lot of the time. MVC has (sensibly) replaced that with more exceptions that map to other error conditions, but HttpRequestValidationException predates MVC.
Now those points made, I can't say I agree with any of them. I'd still say that HttpRequestValidationException means a client error and if it was mis-identified as such, well it was still identified as such, so it's clearly a 400.
However, the final reason is:
While the description of 400 status in RFC 7231 would seem to quite clearly cover such requests, RFC 7231 was published in 2014. HttpRequestValidationException and the handling of it goes back to at least 2003, when RFC 2616 was the relevant RFC. Under the description of 400 in that RFC, 400 could be read as only relating to requests where the actual HTTP message was mal-formed. While some people did use 400 more generally as a catch-all "client did something wrong" response, it wasn't completely clear that doing so was correct.
Even this though gives a reason why 500 may have been a more appropriate reaction 1.5 years ago, not why it should remain. Changing it though would have backwards-compatibility implications so may not be a good idea.
Still, if a given application that you are writing makes conscious use of HttpRequestValidationException (rather than overriding entirely with your own validation that uses a different approach) then it's sensible to catch such exceptions and send a 400 rather than a 500.
This is just how MVC treat HttpRequestValidationException, I don't like it as well but you can manually change it to a BadRequest:
protected void Application_Error()
{
var lastError = Server.GetLastError();
if (lastError is ArgumentException || lastError is HttpRequestValidationException)
{
Server.ClearError();
Response.StatusCode = (int) HttpStatusCode.BadRequest;
}
}

IIS 7 Bad Request (ERROR 400) when querystring has invalid date?

As strange as this may sound, I've been getting a Bad Request (error 400) response from IIS whenever I post a form that has an invalid date in a datetime field, as if IIS knows it's supposed to be a datetime value and is validating it somehow.
UPDATE (added more information)
It's an ASP.NET / MVC 4.0 website.
All datetime fields in the model are declared as string (for other
reasons), so I don't think it's model validation.
This behavior only occurs in one of the servers, all other machines (developer and servers) are ok.
UPDATE 2 (added more information)
It's seems to be a proxy related issue. When accessing the site locally, it works. When accessing it from another computer, returns bad request.
UPDATE 3 (add more information)
Ruled out the "proxy hypothesis". I enabled request tracing in IIS, this was logged:
ModuleName: ManagedPipelineHandler
Notification: 128
HttpStatus: 400
HttpReason: Bad Request
HttpSubStatus: 0
ErrorCode: 0
Notification: EXECUTE_REQUEST_HANDLER
ErrorCode: A operação foi concluída com êxito. (0x0)
I have two posts:
btnProcessarAutuacao=Processar&IdAutuacao=5000038&DataLimiteIdentificacaoCondutor=31%2F12%2F2013+00%3A00%3A00&DscMensagemErro=Numero+do+auto+de+Infra%C3%A7%C3%A3o+A151515+para+o+Orgao+autuador+100107+j%C3%A1+foi+digitalizado&Placa=GVQ3641&AIT=A151515&CodInfracao=7471&DscInfracao=EXC.VELOC.ALEM+50%25+MAX++++++++&CodOrgaoAutuador=100107&DscOrgaoAutuador=GOVERNO+DO+DISTRITO+FEDERAL&DataEmissao=09%2F01%2F2014&DataInfracao=31%2F12%2F2013&HoraAutuacao=10%3A10%3A00&CodMunicipio=643&DscMunicipio=643&Local1=p_local145&Local2=p_local245&X-Requested-With=XMLHttpRequest
2)
btnProcessarAutuacao=Processar&IdAutuacao=5000038&DataLimiteIdentificacaoCondutor=31%2F12%2F2013+00%3A00%3A00&DscMensagemErro=Numero+do+auto+de+Infra%C3%A7%C3%A3o+A151515+para+o+Orgao+autuador+100107+j%C3%A1+foi+digitalizado&Placa=GVQ3641&AIT=A151515&CodInfracao=7471&DscInfracao=EXC.VELOC.ALEM+50%25+MAX++++++++&CodOrgaoAutuador=100107&DscOrgaoAutuador=GOVERNO+DO+DISTRITO+FEDERAL&DataEmissao=31%2F02%2F2014&DataInfracao=31%2F12%2F2013&HoraAutuacao=10%3A10%3A00&CodMunicipio=643&DscMunicipio=643&Local1=p_local145&Local2=p_local245&X-Requested-With=XMLHttpRequest
The second post sends and invalid date (02/31/2014) for the "DataEmissao" parameter and IIS responds with error 400 (Bad Request). The first post has a valid date for the same parameter, IIS responds with OK (200).
That's the only difference I could find in these requests.
Any clues to what is happening?
Finally got it figured out.
I'm doing custom server-side validation, and whenever some field has an invalid value, I set the response code to 400 (Bad Request) and return a custom error message.
When testing locally, my custom error message goes through. When testing remotely, my custom message is replace with a default IIS error page.
All I had to do was add this to web.config:
<system.webServer>
<httpErrors errorMode="Detailed"></httpErrors>
</system.webServer>
So that my custom response text goes without being replaced by the IIS default message.
Got the answer from here: Custom 400 with message being overwritten.
This isn't strange at all :)
IIS doesn't know what the data-type of the query string parameter is supposed to be, but the application framework does. For example, if this is an ASP.NET web-page, then the ASP.NET runtime could be generating the 400, or, alternatively, a programmer could have implemented a check on the type and manually set the return code to 400.
Without more details (and some code!) it's impossible to say precisely where the 400 is being generated, but it will be along these lines...

Categories