HttpHandler does not send response after catching SqlException? - asp.net

This HttpHandler does not send a response if con.Open() throws an exception, for example if faultyConnectionString has an invalid database name. Why?
public void ProcessRequest(HttpContext context)
{
int status = 400;
string message = "Test error!";
string faultyConnectionString = "Data Source=LOCALHOST\\SQLEXPRESS;Initial Catalog=XXX;User ID=XXX;Password=XXX";
try
{
using (SqlConnection con = new SqlConnection(faultyConnectionString))
{
//throw new Exception("This works as expected, and is returned to client");
con.Open();
}
}
catch (Exception ex)
{
status = 500;
message = "Test Exception: " + ex.Message;
}
context.Response.StatusCode = status;
context.Response.StatusDescription = message;
}
Here is how I am handling the call in the client:
function GetContacts() {
$.ajax({
type: "POST",
url: "xxx.ashx",
data: "",
contentType: "application/x-www-form-urlencoded; charset=utf-8",
dataType: "text", // "json",
success: function (response, a, b) {
alert(response.status + " " + response.statusText);
},
error: function (response, a, b) {
alert(response.status + " " + response.statusText);
}
});
}
If I F12 in FireFox it shows me that there is no Response received after the request is sent. In IE it shows me "SCRIPT7002: XMLHttpRequest: Network Error 0x2ef3, Could not complete the operation due to error 00002ef3.". In both cases the jquery ajax call returns status=0 and statusText="error".
If I comment out the two lines inside the catch block then it works as expected, sending the 403 code to the client and ignoring the exception.
Different types of exceptions do not have the same problem. If I throw a new Exception() before con.Open() then it also works as expected. What is different with SqlException?
UPDATE: The very first time I hit ProcessRequest it gets called 5 times in succession before the client shows the status=0 result (breakpoint on first line is hit 5 times).
FIDDLER: If I fire up Fiddler it (fiddler) intercepts the transaction and sends "504 Fiddler - Receive Failure" to my ajax call. Looks like the initial repetition may be a retry mechanism, when fiddler is active it does it 13 times.
Fiddler reports: "Session #xxx raised exception System.Net.Sockets.SocketException An existing connection was forcibly closed by the remote host".

I believe the way your client (browser) handles 404 errors is what is causing this, and each browser type is handling the error differently. 404 errors are specific to "Not Found" so you may want to use a different error code such as a 500 error. More info on error codes is available here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Please keep in mind that passing back detailed error messages to a client could be a security issue due to information leakage. You may be better off passing back a generic error to the client and logging detailed error information on the server side.
Edit:
Testing this locally, the way you are setting context.Response.StatusDescription to contain ex.Message is producing an invalid HTTP response. Try only placing text such as Internal Server Error in there. Additional details can be added to the body of the response using context.Response.Write(bodyText) but please keep the security implications of this in mind.

Related

Angular 2 http service. Get detailed error information

Executing Angular2 http call to the offline server doesn't provide much info in it's "error response" object I'm getting in the Observable's .catch(error) operator or subscription error delegate (they are both share the same info actually). But as you can see on the screen shot of the console there's actual error was displayed by zone.js somehow.
So, how can I get this specific error info (net::ERR_CONNECTION_REFUSED)?
Thanks.
Whenever server do not respond, response.status will be always equal to 0 (zero)
{
type: 3, //ResponseType.Error
status: 0, // problem connecting endpoint
}
Also note, when you are performing CORS request, but origin (url in browser) is not authorized (not in allowed list of host names configured in remote endpoint) the response would be similar to above, with exception to type attribute which will be equal to 4 = ResponseType.Opaque...
This means, connection was made, but for instance, OPTIONS request returned with headers which do not contain origin or HTTPS request was performed from HTTP origin.
You can handle the error messages so they are easier to read. This can definitely be expanded on too:
public Get() {
return this.http.get(this.URL).map(this.extractData)
.catch(this.handleError);
}
public extractData(res: Response) {
let body = res.json();
return body || {};
}
public handleError(error: any) {
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg);
return Observable.throw(errMsg);
}
Check out this part of the docs on error handling.
Without digging in the code, my expectation is that if the server is unreachable, then no response can be returned from the server. Therefore the Response object remains its initialized state.

HTTP.call throws errors instead of returning response

I am working with the Facebook graph API and have run into trouble regarding handling failed requests.
I use this code to create a new post
SocialFacebook.createPosting = function(data) {
var options = {
params: {
access_token : data.tokens.accessToken,
message : data.text
}
};
var url = 'https://graph.facebook.com/' + data.graphId + '/feed';
var response = HTTP.call('POST', url, options).data;
return response;
}
But instead of returning a JS object with error information in the response, it throws an error on failed requests
Exception while invoking method 'createPosting' Error: failed [500] {"error":{"message":"Duplicate status message","type":"FacebookApiException","code":506,"error_subcode":1455006,"is_transient":false,"error_user_title":"Duplicate Status Update","error_user_msg":"This status update is identical to the last one you posted. Try posting something different, or delete your previous update."}}
Because it's wrapped in an Error, the otherwise JSON object is now a string with some other stuff appended to it, which makes it difficult to parse and extract the attributes
Any idea as to why it throws an error, instead of returning a JS object with error details like usually?
Much appreciated
According to the docs, about HTTP.call():
On the server, this function can be run either synchronously or asynchronously. If the callback is omitted, it runs synchronously and the results are returned once the request completes successfully. If the request was not successful, an error is thrown.
So there you have it: since you called HTTP.call() synchronously (without providing a callback), if it responds with an error (in your case, Code 500) the error is thrown and not included in the data.

Getting "401 Unauthorized" error consistently with jquery call to webmethod

I have been struggling to get my jquery call to a webmethod to work. I am being bounced by the server with a "401 Unauthorized" response. I must have an incorrect setting in the web.config or somewhere else that would be preventing a successful call.
Your insight is appreciated!
Call to js function the invokes the jquery call
button.OnClickAction = "PageMethod('TestWithParams', ['a', 'value', 'b', 2], 'AjaxSucceeded', 'AjaxFailed'); return false;";
JavaScript function that makes the jquery call
function PageMethod(fn, paramArray, successFn, errorFn) {
var pagePath = window.location.pathname;
var urlPath = pagePath + "/" + fn;
//Create list of parameters in the form:
//{"paramName1":"paramValue1","paramName2":"paramValue2"}
var paramList = '';
if (paramArray.length > 0) {
for (var i = 0; i < paramArray.length; i += 2) {
if (paramList.length > 0) paramList += ',';
paramList += '"' + paramArray[i] + '":"' + paramArray[i + 1] + '"';
}
}
paramList = '{' + paramList + '}';
//Call the page method
$.ajax({
type: "POST",
url: pagePath + "/" + fn,
contentType: "application/json; charset=utf-8",
data: paramList,
timeout: 10000,
dataType: "json",
success: function(result) { alert('Overjoyed'); },
error: function(result) { alert('No joy'); }
});
}
Web method in page
public partial class WebLayout : System.Web.UI.Page
{
[WebMethod()]
public static int TestNoParams()
{
return 1;
}
[WebMethod()]
public static string TestWithParams(string a, int b)
{
return a + b.ToString();
}
...
Response as seen in Firebug console
json: {"Message":"Authentication failed.","StackTrace":null,"ExceptionType":"System.InvalidOperationException"}
and
"NetworkError: 401 Unauthorized - http://localhost/Care-Provider-Home/Profile/Personal-Profile.aspx/TestWithParams" TestWithParams
I have looked at and read the usual sites on the subject (Encosia, et al), but to avail. Either I am missing a critical piece, or there are some subtleties in the security parameters of my environment that preventing a call.
Here are some other potentially useful tidbits that may impact your diagnosis:
Webmethods in codebehind
Using Sitecore CMS (Does not seem to intefere, never know)
IIS7
.NET 3.5
jQuery 1.3.2
I look forward to your insights and direction--thank you!
Yes, it did get working! Since Sitecore CMS does perform URL rewriting to generate friendly URLs (it assembles the pages in layers, dynamically, similar to Master Page concept), it occurred to me that it may be causing some problem the initially caused the 401 error. I verified this by creating a separate project with a single ASPX--and with some work I was able call the web methods and get values using the jquery. I then created nearly identical ASPX in my web root, but told Sitecore to ignore it when a request is made to it (IgnoreUrlPrefixes in the web.config), after some work I was able also get it to work successfully! Thanks for your help.
The json response from the Firebug Console provides the most telling clue IMO. The System.InvalidOperationException (which strangely rides on a 401 response) suggests something more is at work.
First, googling on "InvalidOperationException webmethod jquery" returns articles which suggest serialization problems can throw this exception. To rule this out, temporarily change "data: paramList" to "data: '{}'". In addition, attach a debugger and see if the exception happens before the method executes or after it completes and attempts to serialize the result.
If the steps above come up empty, you may want to try resetting to a clean web.config or read more of the results that come back from the "InvalidOperationException webmethod" search
What form of authentication are you using, if any? The first thing that comes to mind is to make sure that your webApp in IIS is set to allow anonymous users (if you indeed desire to make the call as an anonymous user). Also that your Authentication mode in web.config is not set to Windows by mistake. If you cannot allow anonymous users and are using forms authentication, then the user will have to be logged in before this call is made from your page.
If the above are properly set, then try making a regular call to the service from server side to make sure the problem is consistent regardless of the point of invocation of the service.
Post more settings if the problem is not resolved. Hope this helps.

500 Internal Server Error when using HttpWebRequest, how can I get to the real error?

I'm trying to improve the information provided in response to an error handled within an app.
This is the code:
Try
httpRequestObj = HttpWebRequest.Create(strRequest)
httpRequestObj.Method = "GET"
httpRequestObj.UseDefaultCredentials = True
* httpResponse = httpRequestObj.GetResponse
Using reader As StreamReader = New StreamReader(httpResponse.GetResponseStream())
strXML = reader.ReadToEnd()
End Using
Catch ex As WebException
'do something with ex
End Try
The webexception is thrown on the * line
Currently all I see in the Exception is "The remote server returned an error: (500) Internal Server Error". I've looked at the exception in debug but the info I need isn't there- I guess the response would need to be read in to see that info but it never gets that far.
If I take the request and paste it into my browser directly I can see the error details in XML format that is returned from the API I'm calling, info like:
<Error>
<description>info I want to get to here</description>
<detail />
<code>info I want to get to here</code>
<source />
<category>info I want to get to here</category>
<file>info I want to get to here</file>
<line>info I want to get to here</line>
<pad />
</Error>
Is there any way I can change this code so that I can get past the 500 error and see the actual response, I'd like to be able to parse this xml to find out the real problem for the failure.
Note: the Exception does have an ex.Response (System.Net.HttpWebResponse), but I can't see the info I need in there, only a load of Header info.
You can get the error response from the exception....
try
{
....
} catch(Exception e) {
if (e is WebException && ((WebException)e).Status==WebExceptionStatus.ProtocolError)
{
WebResponse errResp = ((WebException)e).Response;
using(Stream respStream = errResp.GetResponseStream())
{
// read the error response
}
}
}
System.Net.WebResponse response = null;
try
{
response = wreq.GetResponse();
}
catch (WebException e)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
string error = new System.IO.StreamReader(e.Response.GetResponseStream()).ReadToEnd();
}
}
catch (Exception e)
{
}
as simple as this, You will get entire response in the string error.
Try to use Fiddler. It's debuging proxy, which will show you all data sending between client and server. You'll be able to see all headers and context as well.

httpconnection.getResponseCode() giving EOF exception

I am using Httconnection for connecting to webserver , somtimes request fails causing
EOFException when calling httpconnection.getResponseCode().
I am setting the following headers while making the connection
HttpConnection httpconnection = (HttpConnection) Connector.open(url.concat(";interface=wifi"));
httpconnection.setRequestProperty("User-Agent","Profile/MIDP-2.0 Configuration/CLDC-1.0");
httpconnection.setRequestProperty("Content-Language", "en-US");
I am closing all the connections after processing the request properly.Is this exception is due to exceeding max connections.
It's an internal server error, which return status code 500 in response.
This may be caused by incorrect request, but as well server code or overload may be the reason.
If you have access to server, check event logs.
See also
500 EOF when chunk header expected
Why might LWP::UserAgent be failing with '500 EOF'?
500 EOF instead of reponse status line in perl script
Apache 1.3 error - Unexpected EOF reading HTTP status - connectionreset
Error 500!
UPDATE On the other hand, if it's not response message, but a real exception, then it may be simply a bug, just like in old java
And workaround may be putting getResponseCode() inside of try/catch and call second time on exception:
int responseCode = -1;
try {
responseCode = con.getResponseCode();
} catch (IOException ex1) {
//check if it's eof, if yes retrieve code again
if (-1 != ex1.getMessage().indexOf("EOF")) {
try {
responseCode = con.getResponseCode();
} catch (IOException ex2) {
System.out.println(ex2.getMessage());
// handle exception
}
} else {
System.out.println(ex1.getMessage());
// handle exception
}
}
Talking by connections number limit, read
What Is - Maximum number of simultaneous connections
How To - Close connections
Using HTTPTransportSE, write this before invoke the method "call"
ArrayList<HeaderProperty> headerPropertyArrayList = new ArrayList<HeaderProperty>();
headerPropertyArrayList.add(new HeaderProperty("Connection", "close"));
transport.call(SOAP_ACTION, envelope, headerPropertyArrayList);

Resources