Index: src/apache-2/mod_rivet.c =================================================================== --- src/apache-2/mod_rivet.c (revision 1665838) +++ src/apache-2/mod_rivet.c (working copy) @@ -299,6 +299,51 @@ } } +/* -- Rivet_ExecuteErrorHandler + * + * + * + */ + +static int +Rivet_ExecuteErrorHandler (Tcl_Interp* interp,Tcl_Obj* tcl_script_obj, request_rec* req) +{ + int result; + rivet_server_conf* conf = Rivet_GetConf(req); + Tcl_Obj* errscript; + + /* We extract information from the errorOutbuf variable. Notice that tcl_script_obj + * can either be the request processing script or conf->rivet_abort_script + */ + + Tcl_SetVar( interp, "errorOutbuf",Tcl_GetStringFromObj( tcl_script_obj, NULL ),TCL_GLOBAL_ONLY ); + + /* If we don't have an error script, use the default error handler. */ + if (conf->rivet_error_script) { + errscript = conf->rivet_error_script; + } else { + errscript = conf->rivet_default_error_script; + } + + Tcl_IncrRefCount(errscript); + result = Tcl_EvalObjEx(interp, errscript, 0); + if (result == TCL_ERROR) { + rivet_interp_globals* globals = Tcl_GetAssocData(interp, "rivet", NULL); + CONST84 char* errorinfo = Tcl_GetVar( interp, "errorInfo", 0 ); + + TclWeb_PrintError("Rivet ErrorScript failed!",1,globals->req); + TclWeb_PrintError( errorinfo, 0, globals->req ); + } + + /* This shouldn't make the default_error_script go away, + * because it gets a Tcl_IncrRefCount when it is created. + */ + Tcl_DecrRefCount(errscript); + + return result; +} + + /* -- Rivet_ExecuteAndCheck * * Tcl script execution central procedure. The script stored @@ -316,7 +361,8 @@ * * Returned value: * - * - invariably TCL_OK + * - One of the Tcl defined returned value of Tcl_EvelObjExe (TCL_OK, + * TCL_ERROR, TCL_BREAK etc.) * * Side effects: * @@ -330,7 +376,6 @@ { int result; rivet_server_conf* conf = Rivet_GetConf(req); - rivet_interp_globals* globals = Tcl_GetAssocData(interp, "rivet", NULL); Tcl_Preserve (interp); result = Tcl_EvalObjEx(interp, tcl_script_obj, 0); @@ -337,7 +382,6 @@ if (result == TCL_ERROR) { - Tcl_Obj* errscript; Tcl_Obj* errorCodeListObj; Tcl_Obj* errorCodeElementObj; char* errorCodeSubString; @@ -376,39 +420,35 @@ { if (conf->rivet_abort_script) { - if (Tcl_EvalObjEx(interp,conf->rivet_abort_script,0) == TCL_ERROR) + + /* Ideally an AbortScript should be fail safe, but in case + * it fails we give a chance to the subsequent ErrorScript + * to catch this error. + */ + + result = Tcl_EvalObjEx(interp,conf->rivet_abort_script,0); + if (result == TCL_ERROR) { - CONST84 char *errorinfo = Tcl_GetVar( interp, "errorInfo", 0 ); - TclWeb_PrintError("Rivet AbortScript failed!",1,globals->req); - TclWeb_PrintError(errorinfo,0,globals->req); + //CONST84 char *errorinfo = Tcl_GetVar( interp, "errorInfo", 0 ); + //TclWeb_PrintError("Rivet AbortScript failed!",1,globals->req); + //TclWeb_PrintError(errorinfo,0,globals->req); + + result = Rivet_ExecuteErrorHandler(interp,conf->rivet_abort_script,req); + } } - goto good; } } + else + { + /* Invoke Tcl error handler */ - Tcl_SetVar( interp, "errorOutbuf",Tcl_GetStringFromObj( tcl_script_obj, NULL ),TCL_GLOBAL_ONLY ); + result = Rivet_ExecuteErrorHandler(interp,tcl_script_obj,req); - /* If we don't have an error script, use the default error handler. */ - if (conf->rivet_error_script) { - errscript = conf->rivet_error_script; - } else { - errscript = conf->rivet_default_error_script; } - Tcl_IncrRefCount(errscript); - if (Tcl_EvalObjEx(interp, errscript, 0) == TCL_ERROR) { - CONST84 char *errorinfo = Tcl_GetVar( interp, "errorInfo", 0 ); - TclWeb_PrintError("Rivet ErrorScript failed!",1,globals->req); - TclWeb_PrintError( errorinfo, 0, globals->req ); - } - /* This shouldn't make the default_error_script go away, - * because it gets a Tcl_IncrRefCount when it is created. */ - Tcl_DecrRefCount(errscript); } - -good: /* Tcl_Flush moved to the end of Rivet_SendContent */ @@ -425,7 +465,12 @@ * if a Tcl script. * * This is a separate function so that it may be called from command 'parse' + * + * Returned value: * + * - One of the Tcl defined values returned by Rivet_ExecuteAndCheck (TCL_OK, + * TCL_ERROR, TCL_BREAK etc.) + * * Arguments: * * - TclWebRequest: pointer to the structure collecting Tcl and Apache data @@ -1477,7 +1522,7 @@ if (Rivet_ParseExecFile(globals->req, r->filename, 1) != TCL_OK) { ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r->server, - MODNAME ": Error parsing exec file '%s': %s", + MODNAME ": Error in Rivet_ParseExecFile exec file '%s': %s", r->filename, Tcl_GetVar(interp, "errorInfo", 0)); }