I need to get only the exception message without the call stack or any other string.
I thought that using Exception.Message would be enough, but it keeps giving me the message mixed with the call stack. Do you know how to get rid of all the rest of information that comes with Exception.Message?
try
{
}
catch (Exception ex)
{
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "Message", "alert('" + ex.Message + "');", true);
}
This is what I get when I use ex.Message:
System.Web.Services.Protocols.SoapException: The server can not process the request. ---> System.NullReferenceException: Object reference not set to an instance of an object in . in WebService.ProcessRequestArc.............--- End of inner exception stack trace ---
When what I only need is:
The server can not process the request
Is there any way to get only that part of the message?
You are not using the Message property here...
ex.ToString()
You need
ex.Message
Also, is this Alert only for your convenience? You should consider maybe having an error label on your screen, since the pop-up can always look messy.
EDIT: You should also look to catch more specific exceptions, instead of the catch all type of handling you have. Take a look at the possible exceptions in your try block, and accommodate them...for example...
catch (SoapException ex)
{
//handle
}
catch (Exception e)
{
//handle
}
Make sure the more specific exceptions come before the final Exception block.
Exception.Message is correct for generic Exceptions.
Check out the more detailed info available for SoapException
Here is an example:
namespace ExceptionHandlingTestConsole
{
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("do something");
throw new System.Web.Services.Protocols.SoapException();
//throw new Exception("my exception", new Exception("my inner exception"));
}
catch (System.Web.Services.Protocols.SoapException soapEx)
{
Console.Write("Detail: ");
Console.WriteLine(soapEx.Detail);
Console.Write("Node: ");
Console.WriteLine(soapEx.Node);
Console.Write("Role: ");
Console.WriteLine(soapEx.Role);
Console.Write("Message: ");
Console.WriteLine(soapEx.Message);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
if (ex.InnerException != null)
{
Console.WriteLine("inner exception msg: " + ex.InnerException.Message);
}
}
Console.ReadKey();
}
}
}
Using ex.Message will only return the developer's custom message or, if none was specified, then the name of the exception class (i.e. "Exception of type 'SomeException' was thrown").
public virtual String Message
{
get
{
if (_message != null)
return _message;
if (_className == null)
_className = GetClassName();
return Environment.GetResourceString("Exception_WasThrown", _className);
}
}
If some piece of code further down the chain stored the entire stack trace in the exception's Message property before throwing it, that might explain what you're seeing.
What you're describing is unexpected behavior, and is more typical of calling ex.ToString(), which concatenates the Message (or class name if none), the result of ToString() on the inner exception, and the stack trace.
public override String ToString()
{
String message = Message;
String s;
if (message == null || message.Length <= 0)
s = GetClassName();
else
s = GetClassName() + ": " + message;
if (_innerException != null)
s = s + " ---> " + _innerException.ToString(needFileLineInfo, needMessage) + Environment.NewLine +
" " + Environment.GetResourceString("Exception_EndOfInnerExceptionStack");
string stackTrace = GetStackTrace(needFileLineInfo);
if (stackTrace != null)
s += Environment.NewLine + stackTrace;
return s;
}
You are really close... What you have is this:
try
{
}
catch (Exception ex)
{
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "Message", "alert('" + ex.ToString() + "');", true);
}
What you need is this:
try
{
}
catch (Exception ex)
{
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "Message", "alert('" + ex.Message + "');", true);
}
From the documentation:
Error messages target the developer who is handling the exception. The text of the Message property should completely describe the error and, when possible, should also explain how to correct the error. Top-level exception handlers may display the message to end-users, so you should ensure that it is grammatically correct and that each sentence of the message ends with a period. Do not use question marks or exclamation points. If your application uses localized exception messages, you should ensure that they are accurately translated.
It is also more helpful to use a Web Service reference over an WCF Service reference. See the answer on this post for more information. Or, you could simply just throw a Soap Exception yourself.
Related
I have the following code. Is it ok to just have 1 catch exception ?. What other exception can this piece code can throw ?.
In exception handling , why can't we just have one exception and log all errors ?.
try {
if (File.Exists(inputFilename))
{
// do something
File.WriteAllText()
}
else {
// do somthing
}
}
catch (Exception ex)
{
_eventLog.WriteEntry(ex.Message + "\r\n" + ex.StackTrace, EventLogEntryType.Error);
}
Thanks
What other exception can this piece code can throw
You can see all the possible exceptions in the function page (MSDN):
ArgumentException
ArgumentNullException
PathTooLongException
DirectoryNotFoundException
etc.
why can't we just have one exception and log all errors
You would like to catch different type of exceptions if you want to handle it differently. For example:
try
{
if (File.Exists(inputFilename))
{
// do something
File.WriteAllText(path, contents);
}
else
{
// do somthing
}
}
catch (DirectoryNotFoundException dirNotFoundEx)
{
MessageBox.Show("Directory does not exist.Try to use diffrent folder.");
}
catch (Exception ex)
{
_eventLog.WriteEntry(string.Format("{0}{1}{2}", ex.Message, Environment.NewLine, ex.StackTrace), EventLogEntryType.Error);
}
}
The order of the catch blocks is important. see here
I am new to C# and I'm struggling with very basic stuff... for instance I am now trying to compare an exception that I KNOW will print exactly the phrase "ORA-28007: the password cannot be reused" if I use Response.Write(ex.Message). However, in the block below, the comparison between ex.Message and the string just provided fails and it returns that Unhandled Exception I've put in the else clause... How should I be comparing the exception with the string?
catch (Exception ex)
{
if (ex.Message == "ORA-28007: the password cannot be reused")
{
Response.Write(ex.Message);
// TODO : Correct the exception to be presented in the popup instead of the same page.
// display = "The password cannot be reused! Pick a new one.";
// ClientScript.RegisterStartupScript(this.GetType(),
// "Error.", "alert('" + display + "');", true);
}
else
{
Response.Write("Unhandled exception: " + ex.Message);
}
}
If you're using the Oracle Data Provider for .NET you can catch OracleExceptions instead of Exceptions and get some more details by looking at the Errors property, which gives a list of OracleError objects:
catch(OracleException oex)
{
foreach (OracleError error in oex.Errors)
{
Console.WriteLine("Error Message: " + error.Message);
Console.WriteLine("Error Source: " + error.Source);
if(error.Number == 28007)
{
// do specific stuff
}
}
}
I am using Elmah for error reporting in my applications.
Usually if there's an error I catch it, craft a custom message and throw it back again.
catch (Exception ex)
{
var e = new Exception("Failed to get Intake Statuses <br />"
+ " (#PageNumber = " + pageNumber + ", #PageSize = " + pageSize + ".<br />"
+ " Error: " + ex);
ErrorLogger.LogErrorManually(e);
throw new Exception(e.Message);
}
Now the issue arises if there is an error in the custom error that I am created.
What are the best practices to handle that? Do I create another sub Try/Catch?
You can do the following:
Create a method say A with try catch and lets call your function whose catch you have given in description as B.
In your B catch just use throw so that your stack trace will not go away.
On exception in B catch it will navigate to catch A and thus you can show the message as you like it.
I'm trying to catch unhandled exceptions by using the following code in Program.cs File.
Im trying to create a string containing all the required information of the error.So that i can identify the Point in code where the error occurs.
My question is there a way i can get the following details from the error object after compilation and obfuscation
Name of the form from which the error occurred
The Line Number of code which triggered the error
and any other useful info to pinpoint the exact line of code
private static void OnUnhandledException(Object sender, UnhandledExceptionEventArgs e)
{
string error;
error = e.Exception.Message + "|" + e.Exception.TargetSite;
}
private static void OnGuiUnhandedException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
string error;
error = e.Exception.Message + "|" + e.Exception.TargetSite;
}
I've written the following snippet and have been using it for all of my apps. It goes through all inner exceptions and stack traces of those exceptions that contain most of the info you need:
public static string ExceptionTree(Exception ex)
{
// find all inner exceptions
StringBuilder strbException = new StringBuilder();
do
{
strbException.AppendLine("Exception: " + ex.Message);
strbException.AppendLine("Stack Trace: " + ex.StackTrace);
strbException.AppendLine();
ex = ex.InnerException;
}
while (ex != null);
return strbException.ToString();
}
Just use > System.Environment.StackTrace
try
{
//Exception
throw new Exception("An error has happened");
}
catch (Exception ex)
{
//Open the trace
System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(ex, true);
//Write out the error information, you could also do this with a string.Format
as I will post lower
Console.WriteLine(trace.GetFrame(0).GetMethod().ReflectedType.FullName);
Console.WriteLine("Line: " + trace.GetFrame(0).GetFileLineNumber());
Console.WriteLine("Column: " + trace.GetFrame(0).GetFileColumnNumber());
}
Using string.Format
String.Format("An error has occurred at {0} at line {1}", trace.GetFrame(0).GetMethod().ReflectedType.FullName, trace.GetFrame(0).GetFileLineNumber());
Simply,
(e.ExceptionObject as Exception).ToString();
solve your purpose.
Hello I would like to write my userdefined exception to a log file.
So Instead of throwing my exception I would like to log that message into a txt file.
The constructor for my exception looks like this:
public OpenFileException(string pathToOpen, Exception innerexception)
: base("Couldn't find the path: " + pathToOpen, innerexception)
{
this.pathToOpen = pathToOpen;
}
This is how I am logging my exception at the moment:
try
{
string data = Read(txtLocation.Text);
txtInfo.Text = data;
}
catch (Exception ex)
{
WriteLog("[" + DateTime.Now + "]" + " " + ex.Message);
MessageBox.Show(" ");
throw new OpenFileException(txtLocation.Text, ex);
}
So what I'm asking is. How can I log my string "Couldn't find the path: " to a txt file?
I would normally catch and log the user defined exception outside the normal try/catch
try {
try {
string data = Read(txtLocation.Text);
txtInfo.Text = data;
} catch (Exception ex) {
throw new OpenFileException(txtLocation.Text, ex);
}
....
} catch(OpenFileException ex) {
WriteLog("[" + DateTime.Now + "]" + " " + ex.Message);
MessageBox.Show(" ");
} catch(Exception ex) {
WriteLog("[" + DateTime.Now + "]" + " " + ex.Message);
MessageBox.Show(" ");
}
You are creating a user defined exception so you can handle it differently
It looks a bit overkilling, why don't you use Log4Net and let it write files or send you emails depending on its configuration in the app.config?
basically you get all what you can want out of the box with no effort, then you can concentrate on what matters the most.
even if you decide to keep your current logic, I would anyway create a Logger class which does everything instead of having to specify DateTime.Now and other magic in every single catch block of your application.
You can use, instead of reinvent the wheel, log4net http://logging.apache.org/log4net/ or NLog http://nlog-project.org/wiki/Documentation both worth the effort to learn and use even in simple applications.
You need to find a way to get your exception thrown when a file is not found.
I don't think this is a good idea, because .NET already throws the FileNotFoundException when a file is not found. You should catch that and log the message that way.
try
{
string data = Read(txtLocation.Text);
txtInfo.Text = data;
}
catch (FileNotFoundException ex)
{
string log = String.Format("[{0}] Couldn't find the path: {1}"
, DateTime.Now
, ex.FileName);
WriteLog(log);
}
Don't make a new exception type when one already exists.
(Forgive the idiosyncrasies in my formatting)
From Framework Desing Guidelines:
Do override ToString when your exception provides extra properties.
Then you can just call log.Error(exception) and it will be logged just the way you wrote ToString() without extra actions.