diff --git a/src/error.c b/src/error.c index b6a5bf88360b464e5f987fce262f9f707fb3f814..a5c6873cfdadce6a46e5b156bad687bc645251b8 100644 --- a/src/error.c +++ b/src/error.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: error.c,v 1.147 2006/08/21 18:29:09 grubba Exp $ +|| $Id: error.c,v 1.148 2006/09/20 16:15:55 mast Exp $ */ #define NO_PIKE_SHORTHAND @@ -628,6 +628,24 @@ PMOD_EXPORT DECLSPEC(noreturn) void debug_fatal(const char *fmt, ...) ATTRIBUTE( *! Class for exception objects for errors of unspecified type. */ +/*! @decl string error_message + *! + *! The error message. It always ends with a newline (@expr{'\n'@}) + *! character and it might be more than one line. + *! + *! Code that catches and rethrows errors may extend this with more + *! error information. + */ + +/*! @decl array(backtrace_frame|array(mixed)) error_backtrace + *! + *! The backtrace as returned by @[backtrace] where the error + *! occurred. + *! + *! Code that catches and rethrows errors should ensure that this + *! remains the same in the rethrown error. + */ + #define ERR_DECLARE #include "errors.h" @@ -637,7 +655,8 @@ PMOD_EXPORT DECLSPEC(noreturn) void debug_fatal(const char *fmt, ...) ATTRIBUTE( *! *! @note *! The only supported type to cast to is @expr{"array"@}, which - *! generates and old-style error. + *! generates an old-style error @expr{({@[message](), + *! @[backtrace]()})@}. */ static void f_error_cast(INT32 args) { @@ -646,14 +665,8 @@ static void f_error_cast(INT32 args) if(!strncmp(s,"array",5)) { pop_n_elems(args); - if(GENERIC_ERROR_THIS->error_message) - ref_push_string(GENERIC_ERROR_THIS->error_message); - else - push_int(0); - if(GENERIC_ERROR_THIS->error_backtrace) - ref_push_array(GENERIC_ERROR_THIS->error_backtrace); - else - push_int(0); + apply_current (generic_err_message_fun, 0); + apply_current (generic_err_backtrace_fun, 0); f_aggregate(2); }else{ SIMPLE_BAD_ARG_ERROR("error->cast", 1, "the value \"array\""); @@ -667,10 +680,9 @@ static void f_error_cast(INT32 args) *! Simulates an array *! @array *! @elem string msg - *! Error message. + *! Error message as returned by @[message]. *! @elem array backtrace - *! Backtrace as returned by @[backtrace()] from where - *! the error occurred. + *! Backtrace as returned by @[backtrace]. *! @endarray *! *! @note @@ -688,17 +700,11 @@ static void f_error_index(INT32 args) { case 0: pop_n_elems(args); - if(GENERIC_ERROR_THIS->error_message) - ref_push_string(GENERIC_ERROR_THIS->error_message); - else - push_int(0); + apply_current (generic_err_message_fun, 0); break; case 1: pop_n_elems(args); - if(GENERIC_ERROR_THIS->error_backtrace) - ref_push_array(GENERIC_ERROR_THIS->error_backtrace); - else - push_int(0); + apply_current (generic_err_backtrace_fun, 0); break; default: index_error("error->`[]", Pike_sp-args, args, NULL, Pike_sp-args, @@ -720,7 +726,13 @@ static void f_error_describe(INT32 args) /*! @decl string message() *! - *! Return a readable message describing the error. + *! Return a readable message describing the error. Normally simply + *! returns @[error_message]. + *! + *! If you override this function then you should ensure that + *! @[error_message] is included in the returned message, since there + *! might be code that catches your error objects, extends + *! @[error_message] with more info, and rethrows the error. */ static void f_error_message(INT32 args) { @@ -733,7 +745,8 @@ static void f_error_message(INT32 args) /*! @decl array backtrace() *! - *! Return the backtrace where the error occurred. + *! Return the backtrace where the error occurred. Normally simply + *! returns @[error_backtrace]. *! *! @seealso *! @[predef::backtrace()] @@ -776,7 +789,8 @@ static void f_error__sprintf(INT32 args) /*! @decl int(0..1) _is_type(string t) *! - *! Claims that the error object is an array. + *! Claims that the error object is an array, for compatibility with + *! old style error handling code. */ static void f_error__is_type(INT32 args) { @@ -792,7 +806,8 @@ static void f_error__is_type(INT32 args) push_int(ret); } -/*! @decl void create(string message) +/*! @decl void create(string message, @ + *! void|array(backtrace_frame|array(mixed)) backtrace) */ static void f_error_create(INT32 args) { diff --git a/src/errors.h b/src/errors.h index cedada2d8708ff58e98bf4d52fdfb2d90367011b..08b87cc7c783e6ba8aa5b6b45385edfdaa381ef1 100644 --- a/src/errors.h +++ b/src/errors.h @@ -2,15 +2,17 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: errors.h,v 1.35 2006/08/21 18:36:51 grubba Exp $ +|| $Id: errors.h,v 1.36 2006/09/20 16:15:55 mast Exp $ */ #ifdef ERR_DECLARE #define DECLARE_ERROR(NAME, SCNAME, INHERIT, DECL) \ PMOD_EXPORT struct program *PIKE_CONCAT(NAME,_error_program); \ -ptrdiff_t PIKE_CONCAT(NAME,_error_offset); +ptrdiff_t PIKE_CONCAT(NAME,_error_offset); \ +DECL + +#define ERR_FUNC_SAVE_ID(VAR, NAME, FUNC, TYPE, FLAGS) static int VAR; -#define ERR_VAR(TYPE,CTYPE,RUNTYPE,NAME) TYPE NAME ; #endif #ifdef ERR_EXT_DECLARE @@ -56,6 +58,9 @@ struct PIKE_CONCAT(NAME,_error_struct) { \ #define ERR_FUNC(NAME,FUNC,TYPE,FLAGS) \ ADD_FUNCTION(NAME,FUNC,TYPE,FLAGS); +#define ERR_FUNC_SAVE_ID(VAR, NAME, FUNC, TYPE, FLAGS) \ + VAR = ADD_FUNCTION(NAME,FUNC,TYPE,FLAGS); + #endif #ifdef ERR_CLEANUP @@ -66,6 +71,9 @@ struct PIKE_CONCAT(NAME,_error_struct) { \ } #endif +#ifndef EMPTY +#define EMPTY +#endif #ifndef ERR_INHERIT #define ERR_INHERIT(NAME) @@ -79,14 +87,20 @@ struct PIKE_CONCAT(NAME,_error_struct) { \ #define ERR_FUNC(NAME,FUNC,TYPE,FLAGS) #endif +#ifndef ERR_FUNC_SAVE_ID +#define ERR_FUNC_SAVE_ID(VAR, NAME, FUNC, TYPE, FLAGS) +#endif + DECLARE_ERROR(generic, Generic, EMPTY , ERR_VAR(struct pike_string *,tStr,PIKE_T_STRING,error_message) ERR_VAR(struct array *,tArray,PIKE_T_ARRAY,error_backtrace) ERR_FUNC("cast",f_error_cast,tFunc(tString,tArray),ID_STATIC) ERR_FUNC("`[]",f_error_index,tFunc(tInt01,tMixed),ID_STATIC) ERR_FUNC("describe",f_error_describe,tFunc(tVoid,tString),0) - ERR_FUNC("message", f_error_message, tFunc(tVoid,tString), 0) - ERR_FUNC("backtrace",f_error_backtrace,tFunc(tVoid,tArr(tMixed)),0) + ERR_FUNC_SAVE_ID (generic_err_message_fun, "message", f_error_message, + tFunc(tVoid,tString), 0) + ERR_FUNC_SAVE_ID (generic_err_backtrace_fun, "backtrace", f_error_backtrace, + tFunc(tVoid,tArr(tMixed)),0) ERR_FUNC("_sprintf", f_error__sprintf, tFunc(tOr(tInt,tVoid) tOr(tMapping,tVoid),tString), ID_STATIC) ERR_FUNC("_is_type", f_error__is_type, tFunc(tString, tInt01), ID_STATIC) @@ -141,6 +155,7 @@ DECLARE_ERROR (module_load, ModuleLoad, #undef ERR_VAR #undef EMPTY #undef ERR_FUNC +#undef ERR_FUNC_SAVE_ID #undef ERR_DECLARE #undef ERR_EXT_DECLARE