1

I have a web project that has a page called editemployee.aspx. The code behind is editemployee.aspx.cs. From that code, I call another project, a class library. The method I'm calling in that class library looks like...

        public static Employee GetItem(int employeeid)
        {
            try
            {
                Employee chosenemployee = EmployeeDB.GetItem(employeeid);
                chosenemployee.EmployeeInsuranceRecord = EmployeeInsuranceRecordManager.GetItem(employeeid);
                return chosenemployee;
            }
            catch (Exception ex)
            {
                if (ex is NullReferenceException)
                {
                    //How can I return gracefully from here
                    //without disrupting the user experience?
                }
                else
                {
                    throw ex;  //if it makes it this far, it must be some other unknown error and I need an exception to be thrown for real so I can track down the bug.
                }
            }
        }

Basically this code gets the full employee record from a data access layer based on the passed EmployeeID. If the exception is NullReferenceException, that means that somehow a bogus EmployeeID got through. In that case, what I want to happen is to return to the calling .aspx.cs page, STOP the process of sorting out the Employee right there, and display a JavaScript alert box that says, "The EmployeeID supplied is not valid."

So I tried saying:

            if (ex is NullReferenceException)
            {
                Response.Write("<script>alert('"The EmployeeID supplied is not valid."')</script>"); 
            }

But this does not work from a separate class library like that, it doesn't recognize Response.Write.

Basically I just need a way to signal, from this method, the calling page to just stop and display an error gracefully, rather than give the user a huge ugly unrecoverable error message. Any tips?

CptSupermrkt
  • 6,844
  • 12
  • 56
  • 87
  • Never rethrow an exception by using `throw ex` but simply use `throw`. In the first case you'll loose the stack trace. See this [question](http://stackoverflow.com/questions/730250/is-there-a-difference-between-throw-and-throw-ex) for details. – Stéphane Bebrone Dec 13 '11 at 07:45
  • You guys are all amazing. This will really help me in both solving this particular issue, and in learning more about error-handling in general :) – CptSupermrkt Dec 13 '11 at 07:58

6 Answers6

1

If you want to use the code you tried you can write HttpContext.Current.Response.Write("Whatever")

A better solution would be to display a custom error page. Here's an article that describes how to do that: http://www.asp.net/web-forms/tutorials/deployment/displaying-a-custom-error-page-cs

Svarog
  • 2,188
  • 15
  • 21
1

There are a bunch of ways to do this, but perhaps just return an empty Employee object (or fill it with some marker code), and then at the returning end, check for your marker code, then execute your JS to alert the user.

Something like:

catch (Exception ex)
            {
                if (ex is NullReferenceException)
                {
                    return new Employee { Name = string.Empty }; // no idea what the Emp object looks like...
                    // or
                    return new Employee { Name = "666" };
                }
                    else
                    {
                        throw ex;  //if it makes it this far, it must be some other unknown error and I need an exception to be thrown for real so I can track down the bug.
                    }
                }

Not great, but workable.

Patrick Pitre
  • 843
  • 4
  • 6
  • checking an exception type like this is really ugly. You should never do this! Just catch the NullReferenceException – slfan Dec 13 '11 at 10:34
  • Agreed, but it meets his requirements, as stated. The OP implied that, at least for this specific type of exception, he wanted to be able to return such info to his presentation layer, which in this case is using Javascript. And technically, he is catching the NullReferenceException (although he should do it one level up, and not within a generic Exception). – Patrick Pitre Dec 13 '11 at 19:44
1
  1. First of all your method to get Employee (EmployeeDB.GetItem(employeeid); ) should return null instead of throwing an exception. And you should have a null check before you do anything with the object.

  2. Secondly we should never throw ex unless you are adding additional information. Rather just say "throw" because this won't eat your stack trace. Also, if you are not doing anything in your exception block, just let the exception bubble up and handle there.

In your case you don't need to handle exception if you check for null.

Nitin Rastogi
  • 1,446
  • 16
  • 30
1

Why don't you catch your NullReferenceException from your editemployee.aspx.cs? Something like:

try
{
    var employee = Employee.GetItem(int employeeid)
}
catch(NullReferenceException ex)
{
    Response.Write("<script>alert('"The EmployeeID supplied is not valid."')</script>"); 
}

Plus, you should not use the is operator to filter exception type but add the correct type in the catch statement.

A catch block can specify an exception type to catch. This type is called an exception filter, and must either be the Exception type, or derived from this type. Application-defined exceptions should derive from ApplicationException.

(source)

Finally, it's a recommended practice to throw more specified Exception. In your case a custom EmployeeNotFoundException would be better to throw from your business layer.

catch(NullReferenceException ex)
{
     throw new EmployeeNotFoundException(ex);
}
Stéphane Bebrone
  • 2,713
  • 17
  • 18
  • Soon after I posted I had a feeling that this might be along the lines of what I should do. This just confirms it. Thanks! – CptSupermrkt Dec 13 '11 at 07:59
  • ... and you should not use Response.Write in ASP.NET. You generate invalid HTML (the content is rendered at the begin of the page). – slfan Dec 13 '11 at 11:29
1

The display method is wrong, it should be instead of that :

HttpContext.Current.Response.Write("alert('"The EmployeeID supplied is not valid."')");

Kazaf He
  • 74
  • 5
1

I don't think it is a good idea to use Response.Write from your code, because it will be rendered at the begin of the page (even before the HTML tag). However there are several options:

  1. You either catch the NullReferenceException in the Code-behind page. There you have access to the page and can call ClientScript.RegisterScript or similar.

  2. From the code in your library you can get access to the Response object by using HttpContext.Current.Response.

You should catch the exception like this

catch (NullreferenceException ex)
{
   // handle exception, e.g.
   HttpContext.Current.Response.Write("...");
}  

All other exceptions will be unhandled an walk up the stack.

EDIT: Instead of writing directly to the Response (which is not a good idea), you have the following options:

  1. Redirect to another page (explaining error) with HttpContext.Current.Response.Redirect("Error.aspx");
  2. Register JavaScript

    catch (NullreferenceException ex)
    {
        string javaScript = "alert('The EmployeeID supplied is not valid');";
        HttpContext.Current.Page.ClientScript.RegisterStartupScript(typeof(thePage), "myScript", javaScript, true);
    }
    
slfan
  • 8,950
  • 115
  • 65
  • 78