7220331d99c960562d2dbd5b293bf0002827043a max Sat May 16 08:06:42 2015 -0700 add a hg.conf option that makes sure that errAbort messages are always shown to the user, even when they are before a Content-type, refs #15332 diff --git src/lib/errAbort.c src/lib/errAbort.c index 961fe56..860bcab 100644 --- src/lib/errAbort.c +++ src/lib/errAbort.c @@ -16,53 +16,65 @@ * granted for all use - public, private or commercial. */ // developer: this include is for an occasionally useful means of getting stack info without // crashing // however, it is not supported on cygwin. Conditionally compile this in when desired. //#define BACKTRACE_EXISTS #ifdef BACKTRACE_EXISTS #include #endif///def BACKTRACE_EXISTS #include #include "common.h" #include "hash.h" #include "dystring.h" #include "errAbort.h" - +// errAbort can optionally print a Content-type line and copy errors to stdout, so +// error messages don't lead to a 500 error but are shown in the web browser +// directly. +static boolean doContentType = FALSE; #define maxWarnHandlers 20 #define maxAbortHandlers 12 struct perThreadAbortVars /* per thread variables for abort and warn */ { boolean debugPushPopErr; // generate stack dump on push/pop error boolean errAbortInProgress; /* Flag to indicate that an error abort is in progress. * Needed so that a warn handler can tell if it's really * being called because of a warning or an error. */ WarnHandler warnArray[maxWarnHandlers]; int warnIx; AbortHandler abortArray[maxAbortHandlers]; int abortIx; }; static struct perThreadAbortVars *getThreadVars(); // forward declaration static void defaultVaWarn(char *format, va_list args) /* Default error message handler. */ { if (format != NULL) { + if (doContentType) + { + puts("Content-type: text/html\n"); + puts("Error: "); + vfprintf(stdout, format, args); + fprintf(stdout, "\n"); + fflush(stdout); + } + fflush(stdout); vfprintf(stderr, format, args); fprintf(stderr, "\n"); fflush(stderr); } } static void silentVaWarn(char *format, va_list args) /* Warning handler that just hides it. Useful sometimes when high level code * expects low level code may fail (as in finding a file on the net) but doesn't * want user to be bothered about it. */ { } @@ -188,30 +200,37 @@ void vaErrAbort(char *format, va_list args) /* Abort function, with optional (vprintf formatted) error message. */ { /* flag is needed because both errAbort and warn generate message * using the warn handler, however sometimes one needed to know * (like when logging), if it's an error or a warning. This is far from * perfect, as this isn't cleared if the error handler continues, * as with an exception mechanism. */ struct perThreadAbortVars *ptav = getThreadVars(); ptav->errAbortInProgress = TRUE; vaWarn(format, args); noWarnAbort(); } +void errAbortSetDoContentType(boolean value) +/* change the setting of doContentType, ie. if errorAbort should print a + * http Content type line. */ +{ +doContentType = value; +} + void errAbort(char *format, ...) /* Abort function, with optional (printf formatted) error message. */ { #ifdef COREDUMP abort(); #endif va_list args; va_start(args, format); vaErrAbort(format, args); va_end(args); } void errnoAbort(char *format, ...) /* Prints error message from UNIX errno first, then does errAbort. */ {