Exception Handling Conventions
Exception Handling Conventions Definition:
Development Guidelines for Managing Conditional Errors and Try /Catch Catastrophic Exceptions Using Error Handling Patterns and Best Practices
Exception Handling Conventions Justification:
Management of Runtime Exceptions is essential for a well-behaved Application.
Unhandled Exceptions will cause expected results within an n-tier Enterprise layer Application Dependency Structure.
Common Development Exception Handling Design Patterns are required for a Global understanding of how to manage Runtime Exceptions.
Exception Handling Conventions Standards:
The Modern Developer’s Error Handling Pattern
An effective error handling Design Pattern has two major components:
Conditional Errors – These errors are generally “if/else” blocks that checks for a known predicate and generates a managed useful text message. These messages should be within a Database Message System to eliminate “Magic Strings” with the code. This also allows for custom messages to be updated without code modifications. This complies with the Open / Closed Principles (OCP) of S.O.L.I.D. design.
Catastrophic Exceptions – These errors are created by the .NET run-time and are caught by the .NET Exception base class. There is a robust collection of Exception Types that can be individually caught and managed.
The Return Types for most non-helper Methods are Composite Data Transfer Objects (DTOs).
These DTOs can contain many types both Reference Types and Value Types as Primitives. This enables a behavior Method to return Complex Data in a single Return Type. They are State Objects that manage the State of the Data they contain.
The Modern Developer’s Request / Response DTO Data Pattern
… Passes a Request Composite DTO as a Method Parameter …
…… Returns a Complex Composite DTO as the Method Response DTO…
……… Using the Error Handling Pattern as the Base Class
A DTO that manages State must also manage Errors and Exception on a Type basis, decoupled from the nested types within the State Object.
This can be accomplished with a slight violation of the “Is A” Relationship between a Base Class and its Derived Child Classes.
The Modern Developer chooses to not violate the Behavior Versus State Principle (BVSP), along with a violation of the Liskov Substitution Principle (LSP) that a Class Inheritance Model violates, by implementing The Modern Developer’s Error Handling Pattern.
By implementing the The Modern Developer’s Error Handling Pattern, Object Oriented Programming (OOP) best practices are followed to create a solution that will lower the Total Cost of Ownership (TCO) of the delivered code base over the life cycle of the assembly.
The Behavior Class, “ErrorHandling“, that has public “AddError()” with overload methods can accept a simple string message or an Exception Type to populate the State Class DTO: “ErrorInfo“.
Interface Extension Methods are applied to the “IErrorCommon” Interface and referenced in the implementing Response DTO by referencing the Error Assembly Namespace “ErrorHandlingExtensions“.
The Interface Inheritance Model allows for a Method’s Return State Object, a Response Object, to Implement the IErrorCommon Interface and inherit all the State and Behaviors of the Extensions of the Interface.
This model creates a Behaviour / State Error Design Pattern that manages both Errors and Exceptions from a reusable code base for all derived State DTOs in a simple and enterprise environment
- Process All Actions that Result in Return State Data – Any information that is required to fulfil the requested calling Entity’s request MUST be validated. The return should deliver valid data or an error object with what went wrong information.
- Validate Helper Method Results – Use a “Success” predicate to validate proper Method returns using an “if” statement to guarantee a proper result
- Use the AddError() Method for a String Message – Retrieved a Registered Custom or Global message from the Database Messaging System and populate the DTO Error list using the string overload for the Return State DTO Error object.
- Return the DTO Immediately after Population – End the calling Method as soon as the error objects is populated with a return statement. This ensures that no unwanted artefacts populate the return type. All the required actions have been performed at this point. Do not allow the code to fall through to other code blocks.
- Null References for Returning Types – Use the Error Management process for catching Null References BEFORE the Type is returned. The Helper Method should abstract Null References away from the consuming Method by returning the Boolean default setting of False for the Success predicate. The Null Reference check should always be handled within the called Helper Method.
- Try / Catch Wrappers – Methods that consume Helper Method abstractions for the return type should be wrapped in a Try / Catch block. This code block acts as a Method Anti-corruption Wrapper that prevents unknown run-time exceptions from adversely affecting the calling Software Entity.
- Known Exception Catch Blocks – You can use priority catch blocks for known exceptions ONLY if the known exception has a recovery path. Create Helper Methods that are called for the recovery and validate proper recovery when returned. A recovery action that fails should be treated as an Error NOT a new Exception.
- Exceptions are Expensive – Do not throw a new exception for a known exception. You should handle the exception as an Error and pass the Error object information to the calling class. The overhead for the CLR to handle Exception is very high.
- Be Aware of the Order of Specialized Catch Statements – Catch statements are processed in the order they are coded. Create a hierarchy structure with the most likely to least likely Exceptions. The last Catch statement must always be the global “Exception” Type. This acts as a safety net for all Exceptions that are not defined within a custom known Exception Catch block statement.
- Use the AddError() Method for the First String Message – Retrieved a Registered Custom or Global message from the Database Messaging System and populate the DTO Error list using the string overload for the Return State DTO Error object.
- Use the AddError() Method for a Second Exception Message – Use the Exception overload to add System Exception information such as Source and Stack trace data. This will be available, along with a friendly UI-centric message for the calling Entity to process if required. It will be in the List collection along with all other messages that have “Bubbled UP” from the lower layers. This is accomplished using a variable such as “err” or “error” who’s Type is that of “Exception”.
It is critical that all return DTOs be a Single Composite Complex DTO that contains global DTO properties and Properties that contain a Composite “List<T>” type for all Collection Types.
The Aggregate DTOs within the list will have their own Error Objects that can be processed.
This Pattern creates a Single Object to process Global Object Information while still supporting the Composite’s Aggregates ability to manage their Object Information independently
The following two tabs change content below.
I am a Principal Architect at Liquid Hub in the Philadelphia area specializing in Agile Practices as a Certified Scrum Master (CSM). I use Test Driven Development (TDD) and Acceptance Test Driven Development (ATDD) with Behavior Driven Development (BDD) as my bridge to Agile User Stories Acceptance Criteria in a Domain Driven Design (DDD) implementing true RESTful services