I can't see CreateErrorResponse message in exception. I am passing message "Invalid Parameters" to ThrowResponseException method but i can't read it in exception.
e.Response.RequestMessage gives default detail message but i only need to read "Invalid Parameters".
try
{
If (!ValidString)
{ ThrowResponseException(HttpStatusCode.BadRequest, "Invalid Parameters");}
}
catch (HttpResponseException e)
{
msg = " Status Code: " + e.Response.StatusCode.ToString();
}
private void ThrowResponseException(HttpStatusCode statusCode, string message)
{
var errorResponse = Request.CreateErrorResponse(statusCode,message);
throw new HttpResponseException(errorResponse);
}
I found something similar where they wrap the message in a new exception and pass that exception into the create response. Then they can pull out the text of the error message.
How can I retrieve the exception message from Request.CreateErrorResponse?
return Request.CreateResponse(statusCode, new Exception(message));
Related
I'm incorporating telemetry into my product on all service requests, unfortunately that includes exceptions. A problem I'm having is I surround my requests with a try-catch and if it's successful I log the request and if there's a catch I log the exception than throw the exception so that it still gets propagated up so that it can be debugged. A problem I'm having is that with try-catch I lose all the original data from the original exception caught by my try-catch, which I think would be nice to propagate back up.
public void someFunction(object data)
{
try
{
var response = await request(data);
LogInformation(request: data, response: response);
}
catch (Exception e)
{
throw HandleAndLogException(data, e);
}
}
private HttpResponseException HandleAndLogException(object data, Exception e)
{
LogException(data: data, response: e.Message);
var resp = new HttpResponseMessage(HttpStatusCode.BadRequest) {
Content = new StringContent(e.Message)
};
return new HttpResponseException(resp);
}
So as you can see I create a new HttpResponseException and just append the message to it, but I'd rather propagate back up the exception thrown in it's entirety.
If you want to do something clever/evil, you can use the when keyword to introduce logging without breaking the stack trace on your exception.
See when contextual keyword in the C# reference on MSDN. It's supposed to be used as a filter (the method returns true or false, indicating whether that catch block should be used) but you can do whatever you want with
I think this is what you'd want, although I haven't tested it:
public void someFunction(object data)
{
try
{
var response = await request(data);
LogInformation(request: data, response: response);
}
catch (Exception e) when (HandleAndLogException(data, e))
{
throw;
}
}
private bool HandleAndLogException(object data, Exception e)
{
LogException(data: data, response: e.Message);
return true;
}
I have a project (SharePoint-Addin), that throws a CryptographicException from time to time on my customers machine. This Exception happens before even entering any Controller-Action.
I want to catch that error, analyze it and react accordingly. (Currently my guess would be this is some kind of token expiration, so I want to simply show the login-page if this happens)
I got the following code:
protected void Application_Error(object sender, EventArgs e)
{
_log.Error("ExceptionError occured ");
Exception exception = Server.GetLastError();
if (exception!=null)
{
_log.Error(exception);
if (exception is CryptographicException)
{
Response.Redirect(loginPage, true);
}
}
}
This will (hopefully) work, but this question is not about the code, but about how to force a CryptographicException.
Can I add an "evil header" to a request so this will fire?
Look here at MSDN:
https://msdn.microsoft.com/en-us/library/system.security.cryptography.cryptographicexception(v=vs.110).aspx
private void StringConstructor()
{
// Construct a CryptographicException using a custom error message.
string errorMessage = ("Unexpected Operation exception.");
CryptographicException cryptographicException =
new CryptographicException(errorMessage);
Console.WriteLine("Created a CryptographicException with the " +
"following error message: " + errorMessage);
}
or just
throw new CryptographicException(errorMessage);
Is there any way to get sent error from the smtp to check if the mail is sent successfully?
var smtpClient = new SmtpClient("SmtpServer");
smtpClient.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
smtpClient.SendAsync(mail, userId);
The errors I am looking for are: mail can't be deliver because the mail address not exists, mail box full etc...
Regards,
Meir.
I am not sure what you are trying to achieve but this will helps you.
I assume you're already aware of the DeriveryNotificationOptions property on System.Net.Mail.MailMessage. The only tricky part to using that property is that its enum type represents a bitfield, so you should set it to the sum of the options you want to apply.
For example, if you want delivery notification on delay, failure, or success, you should set the property to
DeliveryNotificationOptions.Delay + DeliveryNotificationOptions.OnFailure + DeliveryNotificationOptions.OnSuccess
Or
this is one method to capture the failure report or any error when the mail has not been sent (failure report)
// Change your Try-Catch to call the new method named 'CheckExceptionAndResend'
// Error handling for sending message
try
{
smtpClient.Send(message);
// Exception contains information on each failed receipient
}
catch (System.Net.Mail.SmtpFailedRecipientsException recExc)
{
// Call method that will analyze exception and attempt to re-send the email
CheckExceptionAndResend(recExc, smtpClient, message);
}
catch (System.Net.Mail.SmtpException smtpExc)
{
// Log error to event log using StatusCode information in
// smtpExc.StatusCode
MsgBox((smtpExc.StatusCode.ToString + " ==>Procedure SmtpException"));
}
catch (Exception Exc)
{
// Log error to event log using StatusCode information in
// smtpExc.StatusCode
MsgBox((Exc.Message + " ==>Procedure Exception"));
}
private void CheckExceptionAndResend(System.Net.Mail.SmtpFailedRecipientsException exObj, System.Net.Mail.SmtpClient smtpClient, MailMessage emailMessage)
{
try
{
for (int recipient = 0; (recipient <= (exObj.InnerExceptions.Length - 1)); recipient++)
{
System.Net.Mail.SmtpStatusCode statusCode;
// Each InnerException is an System.Net.Mail.SmtpFailed RecipientException
statusCode = exObj.InnerExceptions(recipient).StatusCode;
if (((statusCode == Net.Mail.SmtpStatusCode.MailboxBusy)
|| (statusCode == Net.Mail.SmtpStatusCode.MailboxUnavailable)))
{
// Log this to event log: recExc.InnerExceptions(recipient).FailedRecipient
System.Threading.Thread.Sleep(5000);
smtpClient.Send(emailMessage);
}
else
{
// Log error to event log.
// recExc.InnerExceptions(recipient).StatusCode or use statusCode
}
}
MsgBox((exObj.Message + " ==>Procedure SmtpFailedRecipientsException"));
}
catch (Exception ex)
{
// At this point we have an non recoverable issue:
// NOTE: At this point we do not want to re-throw the exception because this method
// was called from a 'Catch' block and we do not want a hard error to display to the client.
// Options: log error, report issue to client via msgbox, etc. This is up to you.
// To display issue as you have before:
MsgBox((exObj.Message + " ==>Email was not sent"));
}
}
Such kind of errors have a asnychronous nature. When sending mail you talk to the local smtp server of your provider. That server afterwards starts to deliver the mail to the target mail system.
So the SmtpClient class can only show you errors occuring while talking to your local smtp server.
Typically when an error like "unknown user" occures on the target system, it will send an email with the failure message to the originator email address.
This post is helpful to me.
By the way if you're using .net 4.0 this one will be the changes on the above code. Sorry for my first post i don't know why it appears that way.
Here's the code:
private void CheckExceptionAndResend(System.Net.Mail.SmtpFailedRecipientsException exObj, System.Net.Mail.SmtpClient smtpClient, MailMessage emailMessage)
{
try
{
for (int recipient = 0; (recipient <= (exObj.InnerExceptions.Length - 1)); recipient++)
{
System.Net.Mail.SmtpStatusCode statusCode;
// Each InnerException is an System.Net.Mail.SmtpFailed RecipientException
//for .net 4.0
//statusCode = exObj.InnerExceptions(recipient).StatusCode;
statusCode = exObj.StatusCode;
//if (((statusCode == Net.Mail.SmtpStatusCode.MailboxBusy) || (statusCode == Net.Mail.SmtpStatusCode.MailboxUnavailable)))
//for .net 4.0
if (((statusCode == System.Net.Mail.SmtpStatusCode.MailboxBusy)
|| (statusCode == System.Net.Mail.SmtpStatusCode.MailboxUnavailable)))
{
// Log this to event log: recExc.InnerExceptions(recipient).FailedRecipient
System.Threading.Thread.Sleep(5000);
smtpClient.Send(emailMessage);
}
else
{
// Log error to event log.
// recExc.InnerExceptions(recipient).StatusCode or use statusCode
}
}
//MsgBox((exObj.Message + " ==>Procedure SmtpFailedRecipientsException"));
}
catch (Exception ex)
{
// At this point we have an non recoverable issue:
// NOTE: At this point we do not want to re-throw the exception because this method
// was called from a 'Catch' block and we do not want a hard error to display to the client.
// Options: log error, report issue to client via msgbox, etc. This is up to you.
// To display issue as you have before:
// MsgBox((exObj.Message + " ==>Email was not sent"));
}
}
I have the following piece of code
try
{
if (!bDebug)
smtp.Send(m);
}
catch (Exception e)
{
wl("Meldingen kunne ikke sendes til en eller flere mottakere.", ConsoleColor.Red);
wl(e.Message, ConsoleColor.DarkRed);
using (var errorfile = System.IO.File.CreateText("error-" + DateTime.Now.Ticks + ".txt"))
{
errorfile.WriteLine(e.StackTrace);
if (e.GetType() == typeof(SmtpFailedRecipientException))
{
var se = (SmtpFailedRecipientException) e;
errorfile.WriteLine(se.FailedRecipient);
}
errorfile.WriteLine(e.ToString());
}
}
Where wl is a shortcut for writing to the console with color, and the text in the first line says "The message could not be sent to one or more recipients.
Previously I only caught the SmtpFailedRecipientException, but when it started failing in some other steps I shoved the generic Exception in there. So the part I'm wondering about is where I'm casting the Exception object into a more specific object to get the FailedRecipient property. Could/should this be done in another more proper way? It seems a bit clunky...
You can have multiple catch branches:
catch (SmtpFailedRecipientException se)
{
using (var errorfile = System.IO.File.CreateText("error-" + DateTime.Now.Ticks + ".txt"))
{
errorfile.WriteLine(se.StackTrace);
// variable se is already the right type, so no need to cast it
errorfile.WriteLine(se.FailedRecipient);
errorfile.WriteLine(se.ToString());
}
}
catch (Exception e)
{
wl("Meldingen kunne ikke sendes til en eller flere mottakere.", ConsoleColor.Red);
wl(e.Message, ConsoleColor.DarkRed);
// for other error types just write the info without the FailedRecipient
using (var errorfile = System.IO.File.CreateText("error-" + DateTime.Now.Ticks + ".txt"))
{
errorfile.WriteLine(e.StackTrace);
errorfile.WriteLine(e.ToString());
}
}
You can try somthing like this(source):
We're going to learn how to catch/handle different types of
exceptions/errors that might occur while sending an email using
ASP.Net. We'll implement error/exception handling using different
exception classes available in System.Net.Mail.
First to learn how to send an email using ASP.Net visit this
link. Notice that in the above article (lead by link) the
'SendEmails' catches only a generic exception and in case ASP.Net
encounters an error while sending email it would be like 'Sending
email failed etc'. We'll extend the error handling functionality for
the above article. So lets get started by openning the solution we
created previously. We already have put a try-catch block that catches
a generic exception that tells very little about what might have gone
wrong. Let's catch different types of exception right away:
Catch the SmtpException: The SmtpException class has a property
'StatusCode' which is actually an enumeration that gets the
error/exception code value returned by the SMTP server when an email
message is transmitted. It also provides more details of
error/exception that can occur during the email sending process. e.g.
catch (SmtpException smtpException)
{ // You can put a switch block to check for different exceptions or errors
// To checks if the destination mailbox is busy
if (smtpException.StatusCode == SmtpStatusCode.MailboxBusy)
throw smtpException;
// To check if the client is authenticated or is allowed to send email using the specified SMTP host
if (smtpException.StatusCode == SmtpStatusCode.ClientNotPermitted)
throw smtpException;
// The following code checks if the email message is too large to be stored in destination mailbox
if (smtpException.StatusCode == SmtpStatusCode.ExceededStorageAllocation)
throw smtpException;
// To check if the email was successfully sent to the SMTP service
if (smtpException.StatusCode == SmtpStatusCode.Ok)
throw smtpException;
// When the SMTP host is not found check for the following value
if (smtpException.StatusCode == SmtpStatusCode.GeneralFailure)
throw smtpException;
}
Catch the SmtpFailedRecipientException: The
SmtpFailedRecipientException class deals with the exception related to
the recipient of the email e.g. SMTP is not able to send the email to
a recipient. The SmtpFailedRecipientException occurs when SmtpClient
is not able to complete a SmtpClient.Send() or SmtpClient.SendAsync()
operation to a particular recipient. To catch this exception use the
following code:
catch (System.Net.Mail.SmtpFailedRecipientException smtpFailedRecipientException)
{
// Get the email that is causing email sending failed exception
String emailCausingException = smtpFailedRecipientException.FailedRecipient;
// Get the status code why and what is actually causing an email sending error
System.Net.Mail.SmtpStatusCode statusCode = smtpFailedRecipientException.StatusCode;
// Take some action either re-send the email again or do some error handling code here
}
Catch the SmtpFailedRecipientsException: The
SmtpFailedRecipientsException is actually a collection of
SmtpFailedRecipientException objects serving the same purpose. It is
used to handle exceptions when SmtpClient is not able to send emails
to one or more recipients.
catch (System.Net.Mail.SmtpFailedRecipientsException smtpFailedRecipientsException)
{
ArrayList emailCausingException = new ArrayList();
foreach (SmtpFailedRecipientException smtpFailedRecipientException
in smtpFailedRecipientsException.InnerExceptions)
{
// Get the email that is causing email sending failed exception
// Add it to a list of emails with exceptions
emailCausingException.Add(smtpFailedRecipientException.FailedRecipient);
// Get the status code why and what is actually causing an email sending error
System.Net.Mail.SmtpStatusCode statusCode = smtpFailedRecipientException.StatusCode;
// Take some action either re-send the email again or do some error handling
// You can also log or print this status code for an individual recipient here
if (statusCode == SmtpStatusCode.MailboxBusy)
{
//Re-Send email after some time
System.Threading.Thread.Sleep(1000);
//smtpClient.Send();
//Email sending code here
}
}
}
Encountered a strange problem with this event, event wrapper and handler:
public delegate void StatusUpdateHandler(string message, Exception exc, SeverityLevel severity);
public event StatusUpdateHandler StatusUpdate;
private void FireStatusUpdate(string message)
{
if (this.StatusUpdate != null)
this.StatusUpdate(message, null, SeverityLevel.None);
}
void scanDocProcessor_StatusUpdate(string message, Exception exc, SeverityLevel severity)
{
try
{
if (exc != null)
{
if (severity >= setSevLevel)
this._logger.Log(message + Environment.NewLine + exc.ToString(), LogEntryType.Emergency, "OCR Submission Processor Status Update", true);
else
this._logger.Log(message + Environment.NewLine + exc.ToString(), LogEntryType.Error, "OCR Submission Processor Status Update", false);
}
else if (severity >= setSevLevel)
{
this._logger.Log(message, LogEntryType.Info, "OCR Submission Processor Status Update", true, true);
}
else
this._logger.Log(message, LogEntryType.Info, "OCR Submission Processor Status Update", false);
}
catch (Exception)
{
EventLog.WriteEntry("Russia OCR Submission Processor", "Could not log status update event: " + exc.ToString(), EventLogEntryType.Information);
}
}
For a period of a few minutes, the _logger stopped logging messages and instead I received these messages in the event log:
Could not log status update event: System.NullReferenceException: Object reference not set to an instance of an object.
at ScannedService.scanDocProcessor_StatusUpdate(String message, Exception exc, SeverityLevel severity)
at ScannedService.Processor.FireStatusUpdate(String message)
at ScannedService.Processor.ProcessQueue(Object Object)
I'm confused how the Event log could get such a stack trace when it should be writing exc.ToString(). I looked at the IL for the scanDocProcessor_StatusUpdate method is not initializing an Exception object. Beyond that I don't know how a nullreferenceexception is getting thrown. When the Log method does catch an exception it swallows it or re-throws it with "throw;". The message parameter is never null and SeverityLevel is an enumeration.
You are throwing an exception in one of the else conditions where ecx is null. In the catch block, you are assuming that ecx is not null, which generates another exception that hides your original one.
You can make your log statement null-safe with the following:
EventLog.WriteEntry("Russia OCR Submission Processor",
String.Format("Could not log status update event: {0}", exc), EventLogEntryType.Information);