# ACTIVESTATE TEAPOT-PKG BEGIN TM -*- tcl -*- # -- Tcl Module # @@ Meta Begin # Package errhan 1.0 # Meta as::author {Emmanuel Frecon} # Meta as::build::date 2015-03-24 # Meta as::license BSD # Meta as::origin http://sourceforge.net/projects/til # Meta description Provides a simple error handling module that allows # Meta description application to possibly continue after an error. # Meta platform tcl # Meta require {Tcl 8.2} # @@ Meta End # ACTIVESTATE TEAPOT-PKG BEGIN REQUIREMENTS package require Tcl 8.2 # ACTIVESTATE TEAPOT-PKG END REQUIREMENTS # ACTIVESTATE TEAPOT-PKG BEGIN DECLARE package provide errhan 1.0 # ACTIVESTATE TEAPOT-PKG END DECLARE # ACTIVESTATE TEAPOT-PKG END TM # errhan.tcl -- # # Provides a simple error handling module that allows # application to possibly continue after an error. # # Copyright (c) 2004-2005 by the Swedish Institute of Computer Science. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. package require Tcl 8.2 package provide errhan 1.0 namespace eval ::errhan { variable EH if {![info exists EH]} { array set EH { loglevel warn err_cb {} } variable log [::logger::init [string trimleft [namespace current] ::]] ${log}::setlevel $EH(loglevel) } namespace export add loglevel } # ::errhan::loglevel -- Set/Get current log level. # # Set and/or get the current log level for this library. # # Arguments: # loglvl New loglevel # # Results: # Return the current log level # # Side Effects: # None. proc ::errhan::loglevel { { loglvl "" } } { variable EH variable log if { $loglvl != "" } { if { [catch "${log}::setlevel $loglvl"] == 0 } { set EH(loglevel) $loglvl } } return $EH(loglevel) } # bgerror -- # # Reroute background errors to the implementation of this # module. This code is partially inherited from tkcon. # # # Arguments: # err Error description # # Results: # None. # # Side Effects: # None directly, see ::errhan::bgerror proc ::bgerror { err } { global errorInfo set body [info body bgerror] rename ::bgerror {} if { [auto_load bgerror]} { rename ::bgerror ::__autoloaded_bgerror proc bgerror err $body if { [::errhan::bgerror $err $errorInfo 1] } { set res [::__autoloaded_bgerror $err] rename ::__autoloaded_bgerror {} return $res } } proc bgerror err $body ::errhan::bgerror $err $errorInfo } # ::errhan::bgerror -- # # Handle background errors and give a chance to other modules to # decide whether this is an error that should lead to an exit or # not. The callbacks that have registered interest in background # errors should return a boolean. If that boolean is true, then # the error is all-right and execution should continue. If not, # then execution should stop, unless another callback has # decided otherwise. # # # Arguments: # err Error description # errInfo Error information message # continue Continue to caller on fatal error (no auto-exit) # # Results: # Return if the error was fatal and the process should exit or not. # # Side Effects: # If one of the callbacks has specified that the error should # proceed or if no callback is registered, the error is printed # out on stderr and the process will exit. proc ::errhan::bgerror { err errorInfo {continue 0}} { variable EH variable log set do_exit 1 if { [llength $EH(err_cb)] > 0 } { set error_ok 0 foreach cb $EH(err_cb) { ${log}::debug "Forwarding error '$err' to callback: $cb" if { [$cb $err] } { ${log}::info "Error '$err' catched and acknowledged" set error_ok 1 break } } if { $error_ok } { set do_exit 0 } } if { !$continue && $do_exit } { puts stderr "ERROR in Tcl Script: $err" puts stderr "\t$errorInfo" exit } ${log}::warn "Error '$err', forwarding it further" return $do_exit } # ::errhan::add -- # # Add a procedure to be called on background errors. # # # Arguments: # proc_cb Procedure to be called back # # Results: # None. # # Side Effects: # None. proc ::errhan::add { proc_cb } { variable EH variable log ${log}::info "Adding new error handler: $proc_cb" lappend EH(err_cb) $proc_cb }