protected virtual void LogException(Exception e, HttpContextBase context)
{
if (e == null)
throw new ArgumentNullException("e");
//
// Fire an event to check if listeners want to filter out
// logging of the uncaught exception.
//
var args = new ExceptionFilterEventArgs(e, context);
OnFiltering(args);
if (args.Dismissed)
return;
//
// Tweet away...
//
HttpWebRequest request = null;
try
{
var status = StringFormatter.Format(_statusFormat, new Error(e, context));
//
// Apply ellipsis if status is too long. If the trimmed
// status plus ellipsis yields nothing then just use
// the trimmed status without ellipsis. This can happen if
// someone gives an ellipsis that is ridiculously long.
//
var maxLength = _maxStatusLength;
if (status.Length > maxLength)
{
var ellipsis = _ellipsis;
var trimmedStatusLength = maxLength - ellipsis.Length;
status = trimmedStatusLength >= 0
? status.Substring(0, trimmedStatusLength) + ellipsis
: status.Substring(0, maxLength);
}
//
// Submit the status by posting form data as typically down
// by browsers for forms found in HTML.
//
request = (HttpWebRequest) WebRequest.Create(_url);
request.Method = "POST"; // WebRequestMethods.Http.Post;
request.ContentType = "application/x-www-form-urlencoded";
if (_credentials != null) // Need Basic authentication?
{
request.Credentials = _credentials;
request.PreAuthenticate = true;
}
// See http://blogs.msdn.com/shitals/archive/2008/12/27/9254245.aspx
request.ServicePoint.Expect100Continue = false;
//
// URL-encode status into the form and get the bytes to
// determine and set the content length.
//
var encodedForm = string.Format(_formFormat, Uri.EscapeDataString(status));
var data = Encoding.ASCII.GetBytes(encodedForm);
Debug.Assert(data.Length > 0);
request.ContentLength = data.Length;
//
// Get the request stream into which the form data is to
// be written. This is done asynchronously to free up this
// thread.
//
// NOTE: We maintain a (possibly paranoid) list of
// outstanding requests and add the request to it so that
// it does not get treated as garbage by GC. In effect,
// we are creating an explicit root. It is also possible
// for this module to get disposed before a request
// completes. During the callback, no other member should
// be touched except the requests list!
//
_requests.Add(request);
var ar = request.BeginGetRequestStream(OnGetRequestStreamCompleted,
AsyncArgs(request, data));
}
catch (Exception localException)
{
//
// IMPORTANT! We swallow any exception raised during the
// logging and send them out to the trace . The idea
// here is that logging of exceptions by itself should not
// be critical to the overall operation of the application.
// The bad thing is that we catch ANY kind of exception,
// even system ones and potentially let them slip by.
//
OnWebPostError(request, localException);
}
}