| Exception handling is an essential part of | | | | states:Exp No: 4026 |
| the programming experience, it polishes the | | | | |
| application and is a bulwark against somewhat | | | | Exp Desc: Index out of boundsAn exception |
| forgivable oversight. We most likely will not | | | | notification needs to provide two types of |
| cover every situation in the first build of | | | | useful information, diagnosis information for |
| an application but at least we can include | | | | the developer or the vendor of the |
| the ability to handle unforeseen runtime | | | | application and explanatory information for |
| exceptions and build some useful tools | | | | the end user or the the vendor's client. |
| utilising exception systems to help with the | | | | Useful details to provide can be:Routine |
| application development process.CUSTOM | | | | name. The name of the routine in which the |
| EXCEPTIONS | | | | exception occurred. |
| | | | |
| =================Custom built exceptions are | | | | Line number. If available the code line |
| a handy tool for both release and development | | | | number or last declared line number when the |
| versions of an application. They can be used | | | | exception occurred. This can really help pin |
| in the following ways:Custom Exceptions as | | | | point the line of code the exception occurred |
| Developer Warnings | | | | within. |
| | | | |
| ---------------------------------------We | | | | Class or module name. This helps locate the |
| can use exceptions to remind us of not | | | | code that threw the exception. |
| providing requisite information to a class or | | | | |
| object. For example: We build a class as an | | | | Call stack: This can be useful to trace the |
| interface to multiple vendor databases, let's | | | | series of events prior to the exception. |
| call it Multiple Vendor Management (MVM) | | | | |
| class. To connect to a particular database we | | | | Active controls or forms: The current active |
| perforce provide the instantiated MVM class | | | | control and/or form which could give a clue |
| with the vendor database type we are | | | | as to what the user was trying to do when the |
| connecting to via a database_type method | | | | exception occurred, although the call stack |
| within the class. The MVM class also has a | | | | could cover this instead. |
| SQL_select method that can be called to | | | | |
| return a recordset from our chosen vendor | | | | Source of the exception: Perhaps the |
| database. Within the SQL_select method is a | | | | exception was caused by an application |
| switch (select case) statement which decides | | | | interactivity or interoperability. |
| how to send the 'select request' to our | | | | |
| chosen database type. If we fail to provide | | | | Time of the exception: Maybe the user went |
| the vendor database type to our class and | | | | to lunch before reporting the exception. It |
| call the SQL_select method at runtime or a | | | | may help to know that when the exception |
| debug compilation, a default (case else) | | | | occurred there was a concurrent hiatus of |
| option within our switch (select case) | | | | intranet connectivity. |
| statement throws a custom exception for | | | | |
| developers. The custom exception will remind | | | | User explanation: An explanation for the |
| a developer during runtime testing that the | | | | user on how the exception impacts their |
| requirements of the class have not been | | | | ability to carry out their tasks. It probably |
| fulfilled during our coding. Below is an | | | | is not necessary to confuse the user with |
| example of where our custom exception can be | | | | exactly what went wrong, just that the |
| used:Private Sub SQL_select(SQL As String)dim | | | | application can not perform their task at the |
| exp_developer_1 as RuntimeException | | | | present time.HANDLING HIDDEN ASSUMPTIONS |
| | | | |
| exp_developer_1 = new RuntimeException | | | | ===========================As a rule I put |
| | | | exception handling into almost every routine |
| exp_developer_1.Message = "'database_type' | | | | to neutralise the spectre of the hidden |
| property is not set." | | | | assumption. I am currently working with a |
| | | | business process diagramming application in |
| exp_developer_1.ErrorNumber = -90000dim rs | | | | which there are scripted reports. One |
| As RecordSetselect case database_typecase | | | | particularly critical report every now and |
| MySQL_DATABASE | | | | then can not complete it's processing, this |
| | | | is a legacy report which has code that makes |
| if Connect_mysql then | | | | inadequate use of exception handling. Every |
| | | | time the report stops I diagnose the problem |
| rs = mysql.SQLSelect(SQL) | | | | as missing Lane symbol names within the |
| | | | diagram the report is trying to process. The |
| end if // Connect_mysqlcase ODBC_DATABASE | | | | developer who had scripted the report |
| | | | mistakenly assumed that there would always be |
| if Connect_odbc then | | | | a name attributed to a Lane symbol, but when |
| | | | a user forgets to enter a Lane symbol's name, |
| rs = odbcdb.SQLSelect(SQL) | | | | the report stalls and has no way to handle |
| | | | the exception that is thrown. The hidden |
| end if // Connect_odbccase REAL_DATABASE | | | | assumption is: A Lane symbol has a name |
| | | | property therefore there is a name value |
| if connect_rbdb then | | | | available within that property. Of course the |
| | | | developer and client most likely tested the |
| // replace any instance of the word DISTINCT | | | | report against well formed diagrams before |
| with UNIQUE to cater for RBDB syntax. | | | | releasing the first build so the exception |
| | | | was never thrown during testing. This is not |
| SQL = | | | | really any party's fault but the result of |
| Replace_passed_regex_strings(SQL,"sDISTINCTs" | | | | human fallibility that has not been catered |
| ," UNIQUE ") | | | | for by utilising exception handling.EXCEPTION |
| | | | LISTENER |
| rs = rbdb.SQLSelect(SQL) | | | | |
| | | | ==================Instead of building a |
| end if // Connect_rbdbcase else | | | | central exception handler to provide |
| | | | exception notification or central exception |
| Raise exp_developer_1end selectException | | | | reporting we could create an class that |
| errd=New MessageDialog | | | | captures exceptions and performs functions |
| | | | based upon the type of exceptions it |
| if err = exp_developer_1 then | | | | receives. One function might be to capture |
| | | | exceptions into a collection and provide |
| d.Set_Icon_Caution_Triangle | | | | advice to calling routines as to what kinds |
| | | | of services the application can provide the |
| else | | | | user at any one time, for example: We have an |
| | | | application that accesses several diverse |
| d.Set_Icon_Stop | | | | data sources which upon start up fails to |
| | | | connect to one of it's data sources and |
| end ifd.ActionButton.Caption = "OK"#if | | | | throws an exception. The exception is handled |
| TargetWin32 or TargetLinux Then | | | | and passed to the Exception Listener. From |
| | | | now on any event that opens a form can call |
| //ERR_MODULE is a constant that holds the | | | | the Exception Listener to see if any details |
| module's/form's name + a full stop | | | | the form provides the user are inaccessible |
| | | | and as a result can disable controls that |
| d.Title = ERR_MODULE + "SQL_select"if err = | | | | allow the editing or reading of those |
| exp_db_error then | | | | details. The latter scenario would allow the |
| | | | user to still perform some duties although in |
| d.Message = d.ERROR_NUMBER_TEXT + | | | | a limited way, which is better than not |
| cstr(exp_db_error.ErrorNumber) + _ | | | | allowing the user to do any work and may |
| | | | still enable the user to finish their work |
| EndOfLine + d.ERROR_DESCRIPTION_TEXT + | | | | tasks with the limited functionality |
| exp_db_error.Message 'message | | | | provided. When I say limited functionality we |
| | | | could be speaking of only a minor disruption |
| elsed.Message = d.ERROR_NUMBER_TEXT + | | | | to functionality overall.Another benefit of |
| cstr(err.ErrorNumber) + _ | | | | an Exception Listener could be the ability to |
| | | | periodically check the collection of |
| EndOfLine + d.ERROR_DESCRIPTION_TEXT + | | | | exceptions it holds and try to resolve the |
| err.message 'message | | | | original cause of the exceptions. In the |
| | | | example above where our application could not |
| end if | | | | access a data source, the Exception Listener |
| | | | could thread a retry of the connection whilst |
| #else//ERR_MODULE is a constant that holds | | | | the application is running and upon a |
| the module's/form's name + a full stop | | | | successful connection notify it's clients of |
| | | | the availability of details from the data |
| d.Message = d.ERROR_ROUTINE_TEXT + | | | | source again and remove the exception from |
| ERR_MODULE + "SQL_select" + EndOfLine | | | | the collection. This is better than the user |
| | | | having to save what they are doing, close the |
| if err = exp_db_error then | | | | application and reopen it to reconnect to a |
| | | | previously inaccessible data source.If our |
| d.Message = d.Message + d.ERROR_NUMBER_TEXT | | | | Exception Listener was a software bus it |
| + cstr(exp_db_error.ErrorNumber) + _ | | | | could publish any messages to it's |
| | | | subscribers within the application and we |
| EndOfLine + d.ERROR_DESCRIPTION_TEXT + | | | | could have a real-time release of limited |
| exp_db_error.message 'message | | | | functionality within forms, web pages and |
| | | | other interfaces.Statistical Analysis of |
| elsed.Message = d.Message + | | | | Application Functionality |
| d.ERROR_NUMBER_TEXT + cstr(err.ErrorNumber) + | | | | |
| _ | | | | |
| | | | --------------------------------------------- |
| EndOfLine + d.ERROR_DESCRIPTION_TEXT + | | | | ----Statistical analysis of the amount of |
| err.message 'message | | | | functionality that can be provided by an |
| | | | application can also be published by the |
| end if | | | | Exception Listener where a missing data |
| | | | source may be determined to reduce the |
| #endifd.AlternateActionButton.Caption = | | | | application's functionality by 25%. The user |
| "Details to Clipboard" | | | | can be notified that the application is only |
| | | | 75% functional which would be useful |
| d.AlternateActionButton.Visible = True | | | | information in a unstable environment. The |
| | | | percentage of functionality would rise or |
| b=d.ShowModalSelect case b | | | | fall based upon exception resolution and |
| | | | exceptions thrown respectively.Exception |
| case d.ActionButton | | | | Cluster Explanation |
| | | | |
| case d.AlternateActionButton | | | | -----------------------------With a |
| | | | collection of exceptions within the Exception |
| d.Details_to_clipboardcase d.CancelButton | | | | Listener we could abstract out a |
| | | | comprehensive explanation of what an |
| end selectfinally | | | | application's current capabilities and |
| | | | limitations are by diagnosing clusters of |
| // clean up | | | | various exceptions and/or exception types. |
| | | | When a user tries to perform a task and |
| if dNil then d=Nil | | | | receives an exception the notification of the |
| | | | exception could provide the ability to open |
| return rs | | | | an explanation dialogue instead of only |
| | | | providing the ability to dismiss the |
| End SubCustom Exceptions used for Call Stack | | | | exception notification. The Exception |
| Retrocession | | | | Listener could provide a comprehensive report |
| | | | upon current application limitations that are |
| | | | producing current system behaviour. For |
| --------------------------------------------- | | | | example, even though our application may have |
| -----A custom exception could be used to | | | | successfully connected to an Account system |
| create a call stack ( break out scenario. For | | | | we cannot retrieve a staff member's salary |
| example, we have an application that is six | | | | transactions because our application cannot |
| calls down a call stack of database | | | | access the necessary employee identification |
| transaction routines and a critical data | | | | details on a Human Resources system that is |
| error has occurred. Instead of handling the | | | | offline. Throwing an exception that informs |
| exception, exiting the routine and allowing | | | | the user that an accounts routine can not |
| the parent routine to continue processing | | | | perform its task does not explain why this |
| it's database transactions we use a custom | | | | has happened and the user will most likely |
| exception to roll back all calls within the | | | | contact the help desk for the explanation, |
| call stack and their transactions. We throw | | | | whereas a comprehensive explanation from the |
| the custom exception within the current | | | | Exception Listener which explains the effects |
| routine whose exception handler rolls back | | | | of a Human Resources system being offline |
| our current routine's database transactions | | | | could instantly explain why the accounts |
| and then throws the custom exception again | | | | routine is failing the user.SUMMARY |
| within the exception handling section of our | | | | |
| routine's code. The exception handler in our | | | | =======Exception handling is an integral and |
| current routine cannot handle the newly | | | | sometimes unappreciated part of any |
| thrown custom exception so transfers control | | | | programming regimen. Points covered |
| back up the call stack to the previous | | | | were:Custom exceptions help with the |
| routine. The previous routine handles the | | | | development process using custom developer |
| custom exception in the same way, and so on | | | | exceptions to remind developers of missed |
| until we reach the top of the stack, having | | | | requirements during coding. |
| rolled back all routines' database | | | | |
| transactions. The initiating routine of the | | | | Custom exceptions can retrocede through a |
| stack can then report the exception or, the | | | | call stack and rollback prior transactions |
| routine that caught the first exception could | | | | and processes. |
| report the exception (see heading Exception | | | | |
| Notification Detail further on in article for | | | | Exceptions can handle the scripting of our |
| why we would do this) and then start the | | | | hidden assumptions. |
| retrocession of the stack.Custom Exception | | | | |
| Generics | | | | Exception Listeners can provide the ability |
| | | | to limit services within an application |
| --------------------------Custom exceptions | | | | allowing the user to perform tasks albeit |
| do not need to be specific in their reporting | | | | some functionality will be disabled. |
| detail, they are custom built so we can | | | | |
| change their messages to better fit the | | | | Exception Listeners can provide |
| circumstance in which we want to throw the | | | | comprehensive explanations of limited |
| exception. For instance, say we have a custom | | | | application behaviour and the possible cause |
| database exception:dim exp_db_error as | | | | of thrown exceptions. |
| RuntimeException | | | | |
| | | | Exception Listeners can provide a |
| exp_db_error.number = -10001 | | | | statistical percentage of application |
| | | | functionality. |
| exp_db_error.message = "Database file can | | | | |
| not be found."We raise this exception within | | | | Exception Listeners can periodically try to |
| a routine where the database file is found | | | | resolve earlier exceptions that reduce a |
| but is corrupt, we can change the message to | | | | system's functionality. |
| better fit the circumstance of the | | | | |
| exception:exp_db_error.message = "Database | | | | Exception notifications can provide enough |
| file is corrupt." | | | | detail for a developer or vendor to pinpoint |
| | | | the cause of an exception in code whilst |
| Raise exp_db_errorThe exception number | | | | concurrently providing a useful explanation |
| relates to database specific issues but the | | | | to assuage user anxiety over an |
| message the user receives is more relevant to | | | | exception.Duane Hennessy |
| the situation than a generic exception | | | | |
| message.EXCEPTION NOTIFICATION DETAIL | | | | Senior Software Engineer and Systems |
| | | | Architect |
| =============================Details | | | | |
| provided in exception notifications perforce | | | | Bandicoot Software |
| should be useful to both the developer and | | | | |
| the end user. A basic exception-type number | | | | Tropical Queensland, Australia |
| and description is usually too vague or | | | | |
| concise to be of use to either party. What | | | | (ABN: 33 682 969 957)Your own personal |
| good is an exception notification that | | | | library of code snippets. |