Error and Exception Handling Policy: Difference between revisions

From OpenPetra Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 4: Line 4:
Input should be given on [[Inconsistent Error and Exception Handling|this]] page.
Input should be given on [[Inconsistent Error and Exception Handling|this]] page.


==Overall==
==Exception Handling==
===Overall===
'''Exceptions should be thrown...'''
'''Exceptions should be thrown...'''
* '''whenever genuine Exceptions occur;'''
* '''whenever genuine Exceptions occur;'''
Line 12: Line 13:
Raising of Exceptions is not considered costly nowadays. We are happy to throw Exceptions across .NET Remoting boundaries as well, as long this occurs infrequently (see [[Error and Exception Handling Policy#Exception Handling across .NET Remoting Boundaries .28Server_-.3E_Client.29|below]]).  
Raising of Exceptions is not considered costly nowadays. We are happy to throw Exceptions across .NET Remoting boundaries as well, as long this occurs infrequently (see [[Error and Exception Handling Policy#Exception Handling across .NET Remoting Boundaries .28Server_-.3E_Client.29|below]]).  


==Practices That Need to be Adhered to==
===Practices That Need to be Adhered to===
===General===
====General====
* '''Exceptions must never be 'swallowed'''', that is, get caught and not get re-raised again!
* '''Exceptions must never be 'swallowed'''', that is, get caught and not get re-raised again!
** What ''is allowed'' is catching of a certain Exception and throwing of another Exception instead (in that Exception handler). However, the new Exception must never be a generalisation. Rather it needs to be a ''specialisation'' of the Exception that gets handled. Alternatively it can be ''a different Exception altogether'', if this is meaningful. The second option needs to be carefully assessed and the pros and cons need to be considered - it must not cause confusion in ''any situation'' where it might be handled by a caller.
** What ''is allowed'' is catching of a certain Exception and throwing of another Exception instead (in that Exception handler). However, the new Exception must never be a generalisation. Rather it needs to be a ''specialisation'' of the Exception that gets handled. Alternatively it can be ''a different Exception altogether'', if this is meaningful. The second option needs to be carefully assessed and the pros and cons need to be considered - it must not cause confusion in ''any situation'' where it might be handled by a caller.
Line 24: Line 25:
* '''TODO'''
* '''TODO'''


===File Operations===
====File Operations====
'''TODO'''
'''TODO'''


===Server-specific Considerations===
====Server-specific Considerations====
'''TODO'''
'''TODO'''


====DB Access====
=====DB Access=====
At the moment our auto-generated '...SubmitChanges' Methods in the openPETRA Datastore return a TVerificationResultCollection, but that should be changed to Exceptions being thrown instead - see [[DB Discussions: Transaction Model, Savepoints, Locking; Exception Handling; Caching#SubmitChanges_Methods | DB Discussions]]!
At the moment our auto-generated '...SubmitChanges' Methods in the openPETRA Datastore return a TVerificationResultCollection, but that should be changed to Exceptions being thrown instead - see [[DB Discussions: Transaction Model, Savepoints, Locking; Exception Handling; Caching#SubmitChanges_Methods | DB Discussions]]!


===Client-specific Considerations===
====Client-specific Considerations====
'''TODO'''
'''TODO'''




==Exception Handling across .NET Remoting Boundaries (Server -> Client)==
===Exception Handling across .NET Remoting Boundaries (Server -> Client)===
All the information that is encapsulated in an Exception is transported without loss of fidelity across .NET Remoting boundaries (this works fine from Linux/mono to Windows/MS .NET as well!).  
All the information that is encapsulated in an Exception is transported without loss of fidelity across .NET Remoting boundaries (this works fine from Linux/mono to Windows/MS .NET as well!).  


Line 43: Line 44:
Be sure to ''never'' throw Exceptions across .NET Remoting boundaries ''in a loop'' of some sort because this could result in a lot of Exceptions which would all need to be remoted, and this would be quite costly!
Be sure to ''never'' throw Exceptions across .NET Remoting boundaries ''in a loop'' of some sort because this could result in a lot of Exceptions which would all need to be remoted, and this would be quite costly!


===Custom Exceptions crossing .NET Remoting Boundaries===
====Custom Exceptions crossing .NET Remoting Boundaries====
If a custom Exception needs to be able to cross .NET Remoting boundaries and keep its specific data in doing so, care needs to be taken that any custom Exception data is not lost!  
If a custom Exception needs to be able to cross .NET Remoting boundaries and keep its specific data in doing so, care needs to be taken that any custom Exception data is not lost!  


Of special importance is the implementation of the Method '<code>GetObjectData</code>': check out some of our custom Exceptions in the Namespace <code>Ict.Petra.Shared.RemotedExceptions</code> to see examples on how this is done properly!
Of special importance is the implementation of the Method '<code>GetObjectData</code>': check out some of our custom Exceptions in the Namespace <code>Ict.Petra.Shared.RemotedExceptions</code> to see examples on how this is done properly!


====Obligatory Namespace for Remoted Exceptions====
=====Obligatory Namespace for Remoted Exceptions=====
All custom Exceptions which can cross .NET Remoting boundaries must be specified in the Namespace <code>Ict.Petra.Shared.RemotedExceptions</code>.
All custom Exceptions which can cross .NET Remoting boundaries must be specified in the Namespace <code>Ict.Petra.Shared.RemotedExceptions</code>.




==Central Place for Maintenance of Unique Error Codes==
==Error Handling==
===Past Implementation and Anticipated Changes===
* In Petra 2.x, a DB Table ('s_error_message') held error codes and the associated error messages centrally. A central function existed which displayed these errors when the software developer supplied the error code.
* In openPETRA we will probably do this differently - a global static Class which holds error codes is envisaged, and a message library which will display errors.
 
===Error Codes===
See [[Error Codes in Openpetra]].
 
===Central Place for Maintenance of Unique Error Codes===
The goal is to have a numbering scheme for unique error codes that  
The goal is to have a numbering scheme for unique error codes that  
* allows new error codes to be introduced easily;
* allows new error codes to be introduced easily;
Line 58: Line 67:
* distinguishes between data verification errors and exceptions.
* distinguishes between data verification errors and exceptions.


===Past Implementation and Anticipated Changes===
See [[Central Inventory of openPETRA Error Codes]].
* In Petra 2.x, a DB Table ('s_error_message') held error codes and the associated error messages centrally. A central function existed which displayed these errors when the software developer supplied the error code.
* In openPETRA we will probably do this differently - a global static Class which holds error codes is envisaged, and a message library which will display errors.

Revision as of 09:36, 16 March 2011

DRAFT DOCUMENT

TODO: This document is a DRAFT and needs to be revised and extended, especially in the areas of Client and Server error handling.

Input should be given on this page.

Exception Handling

Overall

Exceptions should be thrown...

  • whenever genuine Exceptions occur;
  • when other error states (determined by program logic) are detected in code and the handling for those is outside the current program scope (e.g. Method, Property Getter/Setter, etc.).


Raising of Exceptions is not considered costly nowadays. We are happy to throw Exceptions across .NET Remoting boundaries as well, as long this occurs infrequently (see below).

Practices That Need to be Adhered to

General

  • Exceptions must never be 'swallowed', that is, get caught and not get re-raised again!
    • What is allowed is catching of a certain Exception and throwing of another Exception instead (in that Exception handler). However, the new Exception must never be a generalisation. Rather it needs to be a specialisation of the Exception that gets handled. Alternatively it can be a different Exception altogether, if this is meaningful. The second option needs to be carefully assessed and the pros and cons need to be considered - it must not cause confusion in any situation where it might be handled by a caller.
      • Example - ALLOWED: catching a System.Exception and raising e.g. a System.IO.IOException or a custom openPETRA Exception (both result in a specialisation, which is fine).
      • Example - NOT ALLOWED: catching a System.NullReferenceException and raising a System.Exception instead (that would be a generalisation, in which valuable information is lost!).
    • When another Exception is raised than the original Exception, the original Exception must be added as the 'InnerException' of the newly raised Exception. In doing so the original Exception information isn't lost (incl. the code line where the original Exception occured [if the Assembly is built in the Debug rather than the Release configuration]!).
      • This is done by adding the instance of the original Exception as the second Argument when creating the instance of the new Exception.
        • Example: throw new MyAppException("Error caused by trying ThrowInner.", Exp);, where Exp is the instance of the original Exception.
        • Full Example: see Exception.InnerException Property
  • TODO

File Operations

TODO

Server-specific Considerations

TODO

DB Access

At the moment our auto-generated '...SubmitChanges' Methods in the openPETRA Datastore return a TVerificationResultCollection, but that should be changed to Exceptions being thrown instead - see DB Discussions!

Client-specific Considerations

TODO


Exception Handling across .NET Remoting Boundaries (Server -> Client)

All the information that is encapsulated in an Exception is transported without loss of fidelity across .NET Remoting boundaries (this works fine from Linux/mono to Windows/MS .NET as well!).

We are happy to throw Exceptions across .NET Remoting boundaries. However, this this should be done infrequently as throwing Exceptions across .NET Remoting boundaries is more costly then throwing Exceptions in the same Operating System process. Be sure to never throw Exceptions across .NET Remoting boundaries in a loop of some sort because this could result in a lot of Exceptions which would all need to be remoted, and this would be quite costly!

Custom Exceptions crossing .NET Remoting Boundaries

If a custom Exception needs to be able to cross .NET Remoting boundaries and keep its specific data in doing so, care needs to be taken that any custom Exception data is not lost!

Of special importance is the implementation of the Method 'GetObjectData': check out some of our custom Exceptions in the Namespace Ict.Petra.Shared.RemotedExceptions to see examples on how this is done properly!

Obligatory Namespace for Remoted Exceptions

All custom Exceptions which can cross .NET Remoting boundaries must be specified in the Namespace Ict.Petra.Shared.RemotedExceptions.


Error Handling

Past Implementation and Anticipated Changes

  • In Petra 2.x, a DB Table ('s_error_message') held error codes and the associated error messages centrally. A central function existed which displayed these errors when the software developer supplied the error code.
  • In openPETRA we will probably do this differently - a global static Class which holds error codes is envisaged, and a message library which will display errors.

Error Codes

See Error Codes in Openpetra.

Central Place for Maintenance of Unique Error Codes

The goal is to have a numbering scheme for unique error codes that

  • allows new error codes to be introduced easily;
  • ensures that error codes are used and re-used appropriately by the software developers;
  • distinguishes between data verification errors and exceptions.

See Central Inventory of openPETRA Error Codes.