John W. Colby
jwcolby at colbyconsulting.com
Fri May 6 13:39:52 CDT 2005
I am designing a system to create reports to be sent to a client automatically every evening. I did this before and had consistent issues with error handling, msgboxes in error handlers popping up and stopping the process etc. This time there will be no msgboxes, but errors must be reported thus I am trying to build a system that can be called from the error handler or where a message box would pop up. The system will log all such messages. Some thoughts in no particular order. 1) All such messages are errors by definition, since this runs unattended. If a message is necessary, then it is a warning or error. 2) All loops must be checked for an assured terminating condition (no infinite loops). 3) Errors must be graded, i.e. non-critical or critical. 4) Errors must be collected such that if the overall process continues, any errors encountered along the way are logged. I am attempting to modularize the system such that it is broken down into processes. For example: 1) A report generator module creates a set of reports. The report is generated, placed in a directory and it's presence "announced" by an entry in a table. In a simple system the "announced" could just be the presence of the file in the directory, however in my case the file may need to go to several different places. For this reason MY system has to have a place to note that the file was created along with the transfer address to send it to, which I call Transfer Addresses and Transfer Jobs. 2) If the report fails to create for some reason, the failure has to be noted. 3) The report is attempting to report specific "records" in the database, although it is actually a denormalized "dataset". If any "record" fails to report, that error needs to be logged. I.e. I need to be notified that claims XXX were not announced to the client. Obviously this may or may not be a simple failure, i.e. the whole report may fail to create for some reason, or the report may create but certain records may fail to create. The Report generator has "must include" field checking for example, and if any such fields are not filled, that record does not transmit. 4) If the report is created, one or more records is created in a system that is responsible for sending the files. 5) The Transfer Job system will load all open Transfer Jobs and attempt to send them. Some are FTPd, others are sent vie email, and eventually some will be Faxed. The FTP and Email systems are functioning. 6) If the TransferJob fails for any reason, the reason must be logged and the job marked as errored and removed from processing until the error is analyzed and fixed. 7) All errors must be logged, and emailed to myself (or the developer) and the client tech person. Me so I can fix the error and the tech person so that they are aware that some record or report did not go to the client. All of this stuff is functioning (more or less) but one issue I am struggling with is error reporting. I REALLY want a comprehensive error reporting system that will tell me the process (Report Generator, File Transfer etc), the module (specific class or module name) and function / sub, as well as the error code or message. All of my classes have a class name method, which in itself can get a little problematic. The class has a constant that is the class name and a property to report it. However, since a class can have multiple instances, that isn't always sufficient information. Thus each class also has an instance name property which builds up from the Class Name constant plus either just an incrementing integer (worst case) or text information from data the class is collecting. So... I can report the class name easily enough. I have never done so, but it is easy enough to add a private module name constant and a private module name function to report the name of the module for use in error handlers in the module. I am attempting to follow the convention already in place in MS land where objects have a name property. The sub / function name will just be hard coded in the error call. Unfortunately Access / VBA provides no good method of accessing the current function name. That leaves the process name. This gets a little murky because of the modularity. IOW, the error handler itself is a process, and any errors in the error handler module must be reported with the ability to determine that it was a function in module X in the error handler, but... the error handler is not the process, the process is the report generator or the file transfer. OTOH, the File Transfer Job is just a tool initialized at the behest of another process, in this case the report generator. Thus in a "simple" case you have the The Report Generator process calls The File Transfer process (to create a file transfer job for example) Somewhere something calls the Error Handler Process. Any of these processes could generate an error, any class or module within these processes could generate an error, or the error handler itself could generate an error. But the error should report the entire path in the error record, i.e. regardless of at what level the error occurred the error needs to specify that "The Report Generator / File Transfer / clsFile / Function XXX reported Error YYY" or "The report generator / clsProductType / Function KKK reported Error ZZZ". In the meantime, even though all of these modules can report an error, they all need to report the error to the same error handler instance, or you get log files and emails for errors at different levels reported from different error handler class instances. All of which is complicated by the fact that these are standalone modules, and can be used by other processes. Each report generator can be a separate process running on it's own schedule (daily, weekly etc), and uses it's own instance of the File Transfer Process library, with it's own BE holding the accumulated data for that report generator. What I am trying to sort out is how to report the top level process to the error handler. IOW where does THAT piece of information go? I suppose that each process can accept a "Process name" as a parameter as it is initialized, thus if a higher level process initializes it, that process passes in it's own process name, along with any process name it receives when it is initialized. In a perfect world the report generator can generate it's report at midnight. It may generate an error which needs to be reported independently of anything else. The report generator may instantiate the File Transfer process although my inclination is to have that be a process that runs independently of the report generators. IOW, all report generators just create jobs in a table of jobs, and the file transfer process is just always running, or is opened at a specific time. All being created by one illiterate developer, sitting my himself somewhere in the wilds of Connecticut. Sigh. John W. Colby www.ColbyConsulting.com Contribute your unused CPU cycles to a good cause: http://folding.stanford.edu/