0

I'm programming a web app using Perl and Dancer. The logic is not trivial and I want to separate the web page logic (inside Dancer routes) from the business logic that reads and writes from the database. The business logic is going to be stored in several modules the read and write in the database using DBIx::Class.

My question is: What is the best way to keep DB logic in the business Logic modules but still be able to send messages explaining the error to a Web Page and storing more details of the error in a log. I'd like a technique that works with nested functions.

I've been thinking about this, but I haven't found a clear winner. Possible options might be:

  • Catch all the exceptions inside the function and return array ref with the data. If an error happens, the result would be undef.

  • Catch all the exceptions inside the function and return a hash ref. If there hasn't been an error the key "ok" would be equal to 1. A return data would be like this:

    return ({
            ok => 1,
            data => [
                    {
                            name => 'Alfa',
                            year => 2014,
                    },
                    {
                            name => 'Beta',
                            year => 2015,
                    },
            ], 
    });
    
    • In an error case the return value might be something like this:

      return ({
              ok => 0,
              err => 'bussines.deliveries.estimated_date.no_access_dhl',
              err_web => 'No access to DHL site',
      });
      
  • Catch exceptions in the web code using Try::Tiny;

Edit 1: Expanding my question as an answer to Umut Kahramankaptan: I'm only starting with exceptions. In the past days I've read several web pages about expections in perl and how to handle them. What should trigger an exception? Is an exception only caused by an error (not being able to open a file, a division by 0 or a database not responding) or should it be triggered by other cause that blocks the execution of a function?

To explain the last question, I propose several cases:

  • A function executes several read and write operations against a database. If one of them fails it should trigger an exception.

  • Similarly to the previous one a function has to perform several read and write operations with a database. If it finds that it can't continue its sequence (due to some logic or value existing in the database), should in this case trigger the exception?

  • A simpler example could be a login function. If the username and passwords are correct, it should return several user data. What should happen if it fails? return undef? or trigger an exception?

closed as primarily opinion-based by Scant Roger, user53019, user22815 Nov 30 '15 at 20:08

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

3

I would rather go with an OO style exception handling instead of trying to manage error codes.

Normally when you reach an exception, it should mean that your function is not able to work anymore and it should stop. So Option 1 is a waste of resources in a sense.

Option 2, will bring more problems in nested function calls. I think the article Object Oriented Exception Handling in Perl by Arun Udaya Shankar explains the situation very well.

With Option 3, once you catch an exception, you will be in a code block which is dedicated to handling that exception, where you can do logging, web logic error prompting one after another. And if you need to extend your code to include an additional form of communication, only place you will modify will be inside the catch statement.

In short, Try::Tiny to implement OO style exception handling is my preference .

Response to Edit 1: I hope while you were reading you also see how easily you can raise your own exceptions. Here is a page from c2.com that gives use of Exception Class. You can even throw exception depending on your own business logic.

The trick is to decide when your function needs to stop working and return to its caller scope with a message stating why it shouldn't execute anymore. So all your examples could be valid based on a design criteria. Even it is for .Net framework, the guideline from MSDN might give more clarity to you.

To finish with one of your examples. you have a login function which returns undef or user data. You will check if it is undef or not after you call this function. Instead in a try block you can execute the login function, and you will check if you catch the exception or not?

Not the answer you're looking for? Browse other questions tagged or ask your own question.