//---------------------------------------------------------------------------------------- // static int32_t errFunc(MCM_ERR_FUNC_ARGS) { const struct memcache_ctxt *ctxt; struct memcache_err_ctxt *ectxt; MCM_ERR_INIT_CTXT(ctxt, ectxt); debug(("ctxt %p ectxt %p\n", ctxt, ectxt)); debug(("errFunc sev %2d cont=%c misc %p %s:%d %s errnum %d:%s\n", ectxt->severity, ectxt->cont, ectxt->misc, ectxt->funcname, ectxt->lineno, ectxt->errstr, ectxt->errnum, strerror(ectxt->errnum))); /* Dang, ectxt->misc is reset in mcm_err() (through that bzero), so we can't use misc to get our CmemcacheObject. */ CmemcacheObject* self = (CmemcacheObject*) ectxt->misc; /* Outputing the errors is confusing, so don't output anything */ if (self && self->mcErr) { self->mcErr(ctxt, ectxt); } else if (mcErr) { mcErr(ctxt, ectxt); } /* FIXME */ // Throw an exception for errors that will exit/abort. if (ectxt->cont == 'n' || ectxt->cont == 'a') { if (self) { CmemcacheObject* self = (CmemcacheObject*) ectxt->misc; /* might be multiple errors before throwing, only collect first error */ if (!self->throwException) { snprintf(self->exceptionStr, sizeof(self->exceptionStr)-1, "%s", ectxt->errstr); self->throwException = 1; } } // Try not to abort/exit. Without my patch this might segfault libmemcache. ectxt->cont = 'y'; } return 0; }
static int32_t database_cache_error_handler(MCM_ERR_FUNC_ARGS) { const struct memcache_ctxt *ctxt; struct memcache_err_ctxt *ectxt; const char *errno_str; char buf[256]; MCM_ERR_INIT_CTXT(ctxt, ectxt); if (ectxt->errnum != 0) errno_str = strerror(ectxt->errnum); else errno_str = NULL; /* The following IF statement is the core stuff to TRAP fatal errors and avoid libmemcache to abort() */ if (ectxt->cont == 'a' || ectxt->cont == 'n'){ ectxt->cont = 'y'; memcached_data.has_error = 1; } /* * Quick explaination of the various bits of text: * * ectxt->errmsg - per error message passed along via one of the MCM_*_MSG() macros (optional) * ectxt->errstr - memcache(3) error string (optional, though almost always set) * errno_str - errno error string (optional) */ if (ectxt->errmsg != NULL && errno_str != NULL && ectxt->errmsg != NULL) snprintf(buf, sizeof(buf)-1, "%s():%u: %s: %s: %.*s\n", ectxt->funcname, ectxt->lineno, ectxt->errstr, errno_str, (int)ectxt->errlen, ectxt->errmsg); else if (ectxt->errmsg == NULL && errno_str != NULL && ectxt->errmsg != NULL) snprintf(buf, sizeof(buf)-1, "%s():%u: %s: %.*s\n", ectxt->funcname, ectxt->lineno, errno_str, (int)ectxt->errlen, ectxt->errmsg); else if (ectxt->errmsg != NULL && errno_str == NULL && ectxt->errmsg != NULL) snprintf(buf, sizeof(buf)-1, "%s():%u: %s: %.*s\n", ectxt->funcname, ectxt->lineno, ectxt->errstr, (int)ectxt->errlen, ectxt->errmsg); else if (ectxt->errmsg != NULL && errno_str != NULL && ectxt->errmsg == NULL) snprintf(buf, sizeof(buf)-1, "%s():%u: %s: %s\n", ectxt->funcname, ectxt->lineno, errno_str, ectxt->errstr); else if (ectxt->errmsg == NULL && errno_str == NULL && ectxt->errmsg != NULL) snprintf(buf, sizeof(buf)-1, "%s():%u: %.*s\n", ectxt->funcname, ectxt->lineno, (int)ectxt->errlen, ectxt->errmsg); else if (ectxt->errmsg == NULL && errno_str != NULL && ectxt->errmsg == NULL) snprintf(buf, sizeof(buf)-1, "%s():%u: %s\n", ectxt->funcname, ectxt->lineno, errno_str); else if (ectxt->errmsg != NULL && errno_str == NULL && ectxt->errmsg == NULL) snprintf(buf, sizeof(buf)-1, "%s():%u: %s\n", ectxt->funcname, ectxt->lineno, ectxt->errmsg); else snprintf(buf, sizeof(buf)-1, "%s():%u\n", ectxt->funcname, ectxt->lineno); switch (ectxt->severity) { case MCM_ERR_LVL_INFO: cw_log(LOG_DEBUG,"%s",buf); break; case MCM_ERR_LVL_NOTICE: cw_log(LOG_NOTICE,"%s",buf); break; case MCM_ERR_LVL_WARN: cw_log(LOG_WARNING,"%s",buf); break; case MCM_ERR_LVL_ERR: cw_log(LOG_ERROR,"%s",buf); break; case MCM_ERR_LVL_FATAL: cw_log(LOG_ERROR,"** %s",buf); break; default: cw_log(LOG_NOTICE,"%s",buf); break; } return 0; }