Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2013-03

How do Lazarus users handle exceptions in procedures which are running in data modules?

5 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Frank Church

How do Lazarus users handle exceptions in procedures which are running in data modules?

A lot of the guides and examples demonstrate raising exceptions, which generally display dialogs to the user that an exception has occurred.

But what is the best way to handle them if they occur inside data modules as they may not have a user interface, or are even not supposed to have any, but then somehow communicate the exception back to the user interface is required?

In my view it is either by passing a var parameter to the procedure in the data module which returns some information about the error, or changing the procedure into a function and return info about the error in the result. On the other hand using functions messes up the reading of the program because it make the return values appear to be the subject of the computations.

What are the best practices in Lazarus or Delphi with dealing with this kind of situation? Are there some frameworks for handing this type of problem?

Frank Church ======================= http://devblog.brahmancreations.com

Reply by email

Hans-Peter Diettrich
to Frank Church
Show quoted text 5 lines
How do Lazarus users handle exceptions in procedures which are running in data modules? A lot of the guides and examples demonstrate raising exceptions, which generally display dialogs to the user that an exception has occurred.

Sample code showing an error message is *not* useful in real life exception handling, because Application will do that for you and show the error message.

But what is the best way to handle them if they occur inside data modules as they may not have a user interface, or are even not supposed to have any, but then somehow communicate the exception back to the user interface is required?

Exceptions are not intended for immediate handling. Instead an exception should be handled in a place where it can be handled in a *meaningful* way, somewhere up in the call stack. Only if you have a loop or a sequence of statements, which should continue even if something goes wrong in on statement or iteration, you catch exceptions there.

In a sequence of statements you have to enclose every error prone statement with an try-except block or, when the statement is a call, enclose the code in that subroutine. In the exception handler you can set variables to meaningful values, to keep the code following the try-except block working. This can obviously be done only in places where you know about the following statements, and how they should behave after an exception has occured.

In a loop you enclose the entire loop body with try-except, and issue a message like "in ... iteration #... failed due to ...", or whatever the user should know. You also can set a flag and report "some iterations failed..." after the loop.

Of course not all exceptions can be handled this way. Some may be fatal, others may be neglectable to some degree. Therefore only selected exceptions should be handled in an except block, i.e. those which do not prevent the following code from working. The unhandled exceptions can be handled in subroutines further up in the call stack, when such handling is possible there. This means that exceptions should have specific types, which can be recognized in different levels of application exception handling.

DoDi

Reply by email

Antonio Fortuny
to Frank Church: How do Lazarus users handle exceptions in procedures which are running in data modules? A…

Le 05/03/2013 16:14, Frank Church a ?crit :

Show quoted text 17 lines
How do Lazarus users handle exceptions in procedures which are running in data modules? A lot of the guides and examples demonstrate raising exceptions, which generally display dialogs to the user that an exception has occurred. But what is the best way to handle them if they occur inside data modules as they may not have a user interface, or are even not supposed to have any, but then somehow communicate the exception back to the user interface is required? In my view it is either by passing a var parameter to the procedure in the data module which returns some information about the error, or changing the procedure into a function and return info about the error in the result. On the other hand using functions messes up the reading of the program because it make the return values appear to be the subject of the computations.

Right. This is why I decided once for all to report errors AND return values on a function call. I use the following proto: function DoingSomething(const arg1: type;...; out Msg: String): Boolean (or whatever the result should be). This assumes, of course, that the function returns some meaningfull information when everything runs well and a predefined error value otherwise (I often use -1 in case of integers). The OUT argument Msg will be used by the function to explain why the thuction failed and will be empty if the function works OK. The Msg out parameter could be whatever you need, not olny a string.

What are the best practices in Lazarus or Delphi with dealing with this kind of situation? Are there some frameworks for handing this type of problem?

The only rule that I always apply concerning exception handling is to process the exception depending on if the concerned code is playing in the data layer or the presentation layer. Said in other words, do I play with data or the user interface ?
Obviously, in a DM you are in the data layer.
Rule: in data layer push exception results (re-raise the exception for instance) to the caller whereas on presentation layer, display the exception to the user and ask him what action to do next. In any case I never mix data and presentation layers processing. This also means that data layer is never affected by what happens in the presentation layer and vice-versa except by the natural ways: functions, procedures and object properties and methods.

Reply by email

Marcos Douglas
to Antonio Fortuny
Antonio Fortuny wrote 46 lines
Le 05/03/2013 16:14, Frank Church a ?crit : > How do Lazarus users handle exceptions in procedures which are running > in data modules? > > A lot of the guides and examples demonstrate raising exceptions, which > generally display dialogs to the user that an exception has occurred. > > But what is the best way to handle them if they occur inside data > modules as they may not have a user interface, or are even not > supposed to have any, but then somehow communicate the exception back > to the user interface is required? > > In my view it is either by passing a var parameter to the procedure in > the data module which returns some information about the error, or > changing the procedure into a function and return info about the error > in the result. On the other hand using functions messes up the reading > of the program because it make the return values appear to be the > subject of the computations. Right. This is why I decided once for all to report errors AND return values on a function call. I use the following proto: function DoingSomething(const arg1: type;...; out Msg: String): Boolean (or whatever the result should be). This assumes, of course, that the function returns some meaningfull information when everything runs well and a predefined error value otherwise (I often use -1 in case of integers). The OUT argument Msg will be used by the function to explain why the thuction failed and will be empty if the function works OK. The Msg out parameter could be whatever you need, not olny a string. > > What are the best practices in Lazarus or Delphi with dealing with > this kind of situation? Are there some frameworks for handing this > type of problem? The only rule that I always apply concerning exception handling is to process the exception depending on if the concerned code is playing in the data layer or the presentation layer. Said in other words, do I play with data or the user interface ? Obviously, in a DM you are in the data layer. Rule: in data layer push exception results (re-raise the exception for instance) to the caller whereas on presentation layer, display the exception to the user and ask him what action to do next. In any case I never mix data and presentation layers processing. This also means that data layer is never affected by what happens in the presentation layer and vice-versa except by the natural ways: functions, procedures and object properties and methods.

IMHO if you always functions that have a boolean result and an output message parameter, you do not uses the power of Exceptions. Depends, depends... but you can use some public methods with boolean results but the private methods raises an exception if something was broken, then you catch the exception - that you know what this is because this is your code - and returns True/False in the public method.

In many cases I have an Exception type for each unit and one for each class that inherited from this global type unit.

Marcos Douglas

Reply by email

Antonio Fortuny
to Marcos Douglas
Show quoted text 8 lines
IMHO if you always functions that have a boolean result and an output message parameter, you do not uses the power of Exceptions. Depends, depends... but you can use some public methods with boolean results but the private methods raises an exception if something was broken, then you catch the exception - that you know what this is because this is your code - and returns True/False in the public method.

This is another opinion and I'll not argue against it. It's simply a different view of mine. Anyway. When dealing with data, that's what I basically do in a DM, all components I use are supposed to work with exceptions. That's why all lines calling component methods or properties which could potentially raise an exception are enclosed in my own try...except blocks. Those blocks are there to avoid the program to crash whithout letting the user know what's going on as far as the presentation layer does its own work.
In a normal run, I'm not interested at all on which piece of code fails, I just want to know that somethig failed and why. Using the more or less explicit exception message most of the time it is fair enough to inform the user (who then in turn will take developper's advice)

In many cases I have an Exception type for each unit and one for each class that inherited from this global type unit.

I do this sometimes too. But only when the exception type is a means of warning the presentation layer that a special situation araised. And I can then modulate the exception message in a more convenient way.

Show quoted text 9 lines
Marcos Douglas -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply by email