locked
Basic Exception Handling - please advise.. RRS feed

  • Question

  • User-622324082 posted

    I posted a similar question about 6 months ago, as I thought I would be working with exception handling at that time.  Six months later, I am starting to work on this with my project and I am looking for guidance. 

    I have my application setup using the N-Layered Web Application documented by Imar Spaanjaars located at http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=476

    My question is basically this:  When an exception occurs in my DAL or BLL, what do I do with it?  Currently, my DAL methods look similar to..

    .....

    Try

    ' create the data adapter
    Dim myDataAdapter As New SqlDataAdapter(myCommand)
    Dim myDataSet As New DataSet()

    myDataAdapter.Fill(myDataSet)
    ' add a data relation
    myDataSet.Relations.Add("Tanks", myDataSet.Tables(0).Columns("GasSiteId"), myDataSet.Tables(1).Columns("GasSiteId"))
    ' extract the dataset
    myTempList = GetGasSiteCollectionFromDataSet(myDataSet)

    For Each gs As GasSite In myTempList
    myGasSite = gs
    Next


    Catch ex As Exception

    End Try

    .....

    Currently, if an error occurs in my DAL, the only way I know is because my Presentation Layer (PL) does not produce the desired result.  Ideally, I would like some area on the page to say.... "Oops!  An error has occured and been logged."

    I have been doing a lot of reading on this, but I don't seem to be getting the answers I am looking for. 

    I know that I should Throw an exception, however:

     -- Should this be a custom exception type, e.g. if I created a DataAccessException or a BusinessLayerException class or something like this?

     -- When I thrown an exception, where is it caught?

    -- Ideally, I would like to log exceptions in a db table or file.  How is this normally done?

    .....

    Currently in my application, in the PL:

    in Page_Load:

      myGridview.Datasource = OrderManager.GetList() ' returns all orders in the database
      myGridview.Databind()

    In the BLL:

      Public Shared Function GetList() as OrdersCollection
           Return OrderDB.GetList() 
      End Function

    In the DAL:

    Public Shared Function GetList() as OrdersCollection"
      .......
      Try
           ' run the stored procedure and populate an OrdersCollection

      Catch ex as Exception

      End Try

      ...

      End Function

    Should I wrap the PL call and BLL call in a Try...Catch??


    I think this is it for now, though I am sure that as replies come in, I will have more questions.


    Thanks in advance for any input.

    sb

    Tuesday, January 5, 2010 4:42 PM

Answers

  • User1753744165 posted

    You only need to wrap the exception in a custom exception if you are going to do something with it further down the line. You'll have a try catch in your UI code that might have multiple different calls to multiple different things, and you might want to display a different message for each (a call to get a person verse an update). If you arent ever going to handle them differently, just throw the Exception.

    UI:

    try {

    getPerson();

    updateStatus(personId);

    catch (PersonException pe) {

    }

    catch (StatusException se) {

    }

     

    Nick

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, January 8, 2010 12:58 PM

All replies

  • User527588884 posted

    check out the MS exception handeling block http://msdn.microsoft.com/en-us/library/cc309212.aspx , also what you will want to do is 

    bubble the exceptions up to the user or to an error log if the error is not going to stop the running of the application.

    Tuesday, January 5, 2010 5:43 PM
  • User1753744165 posted

    I would log the error inside the DAL or BAL, but still bubble it up through to the Client so the end user can be notified of a problem. Some of my applications are windows applications, so I dont want to log the error on the client's machine so I log it where ever it happens. This also translates well to other types of applications as well.

     

    Nick

    Wednesday, January 6, 2010 9:29 AM
  • User854688209 posted

    I would suggest to log SQLException in DAL and Generic Exception in the PL, the exception in BLC will bubble up to PL. 

    If you catch SQLException in DAL, you will able to log more detailed database error, normal Exception class doesn't provide detailed specific exception.

    Note: Try to avoid Try Catch block where ever possible and when the error can be handled by using if condtion. Try catch is always overhead and degrade performance.

     

    Wednesday, January 6, 2010 1:56 PM
  • User-622324082 posted

    Thanks for the replies.  I have read the link posted above about the Microsoft Exception Handling Block - and I feel like it is a goose chase.  I read the link mentioned - and then went to reading some of the Developing Applications with the Exception Handling Application Block mentioned at the bottom of the link posted - which brings you to 3 sets of 3-5 articles each and it just feels like some big recursive mess.....(the process of learning it)

    So let's simplify my original question. 

    In my DAL I have a stored procedure that returns 2 tables, orders and order details.  I populate an order object (which has a property OrderDetails which is a collection of order detail objects).

    In order to accomplish this goal, I execute a stored procedure, fill a dataset, create a relationship, and populate my objects.

    Let's say for some reason, the relationship failes and causes an exception.

    My code will now look like:

    ...

    Try
    'executes the command
    myDataAdapter.Fill(myDataSet)

    myDataSet.Relations.Add("OrderDetails", myDataSet(0).Columns("OrderId"), myDataSet.Tables(1).Columns("OrderId")

    myCollection = GetOrdersFromDataset(myDataSet)

    Catch ex As Exception
    Throw ex
    End Try

    ...
    I see above people mention not to use too many Try..Catch blocks, but rather let exceptions "bubble up".  I assume this means - Do not use a try...catch in my BLL.  The exception will occur in my DAL... and "bubble" to my BLL?? Because my BLL does not have a try..catch it will then "bubble" to my PL??

    So if this is true, the exception is now to my PL.  I just called myGrid.Datasource = OrdersBLL.GetOrders() - and an exception occured in my DAL (creating the relationship)...I want to display in a label control on my page.. "Oops!  an error has occured getting orders." 

    How is this done??  When I do throw ex, where does it go??  How do I use it?


    Hope this makes sense.

    sb



    Thursday, January 7, 2010 2:52 PM
  • User1753744165 posted

    You would still catch the exception in the DAL via a try catch. You'd log the exception somewhere, and then throw the exception.

    try {

    //Dal work

    catch (Exception ex) {

    //Do log work

    throw new DALException("Error in my code", ex);

    }

    Inside the BAL, there is no try catch for this, which will allow it to bubble up to the client.

     

    Nick

    Friday, January 8, 2010 8:42 AM
  • User-622324082 posted

    So at this point, any point in my code that goes to get information from my BLL--->DAL from my PL, I should wrap it in a Try..Catch?


    So in the DAL, the exception happens, I should log it in the DB, and throw a new ex with a different message (a custom exception).  Then, in my PL, if my call to the other layers is wrapped in a Try..Catch, my custom exception is then caught and I can set a label.text = "An error has occured".

    I think I am on the right track, thank you for bearing with me....



    Friday, January 8, 2010 11:04 AM
  • User1753744165 posted

    You only need to wrap the exception in a custom exception if you are going to do something with it further down the line. You'll have a try catch in your UI code that might have multiple different calls to multiple different things, and you might want to display a different message for each (a call to get a person verse an update). If you arent ever going to handle them differently, just throw the Exception.

    UI:

    try {

    getPerson();

    updateStatus(personId);

    catch (PersonException pe) {

    }

    catch (StatusException se) {

    }

     

    Nick

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, January 8, 2010 12:58 PM
  • User854688209 posted

    So at this point, any point in my code that goes to get information from my BLL--->DAL from my PL, I should wrap it in a Try..Catch?


    So in the DAL, the exception happens, I should log it in the DB, and throw a new ex with a different message (a custom exception).  Then, in my PL, if my call to the other layers is wrapped in a Try..Catch, my custom exception is then caught and I can set a label.text = "An error has occured".

    I think I am on the right track, thank you for bearing with me....



     

    Yep you are on the right track. If you implement as per above said, it would resolve your exception handling issue and it is the right way to do it.

     

    Friday, January 8, 2010 1:55 PM
  • User-1067358373 posted

    Check out Exception Handling advice from 4guysfromrolla.com


    http://www.4guysfromrolla.com/articles/081209-1.aspx

    Friday, January 8, 2010 4:09 PM