How to get Exception messages without the call stack

13,193

Solution 1

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.

Solution 2

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;
}

Solution 3

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();
        }

    }
}

Solution 4

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.

Share:
13,193
eddy
Author by

eddy

Updated on June 18, 2022

Comments

  • eddy
    eddy almost 2 years

    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?