void STACK_ARGS I_FatalError(const char *error, ...) { static BOOL alreadyThrown = false; gameisdead = true; if (!alreadyThrown) // ignore all but the first message -- killough { alreadyThrown = true; char errortext[MAX_ERRORTEXT]; va_list argptr; va_start(argptr, error); myvsnprintf(errortext, MAX_ERRORTEXT, error, argptr); va_end(argptr); // Record error to log (if logging) if (Logfile) { fprintf(Logfile, "\n**** DIED WITH FATAL ERROR:\n%s\n", errortext); fflush(Logfile); } throw CFatalError(errortext); } if (!HasExited) // If it hasn't exited yet, exit now -- killough { HasExited = 1; // Prevent infinitely recursive exits -- killough exit(-1); } }
void STACK_ARGS I_Error(const char *error, ...) { va_list argptr; char errortext[MAX_ERRORTEXT]; va_start(argptr, error); myvsnprintf(errortext, MAX_ERRORTEXT, error, argptr); va_end(argptr); throw CRecoverableError(errortext); }
CVMAbortException::CVMAbortException(EVMAbortException reason, const char *moreinfo, va_list ap) { SetMessage("VM execution aborted: "); switch (reason) { case X_READ_NIL: AppendMessage("tried to read from address zero."); break; case X_WRITE_NIL: AppendMessage("tried to write to address zero."); break; case X_TOO_MANY_TRIES: AppendMessage("too many try-catch blocks."); break; case X_ARRAY_OUT_OF_BOUNDS: AppendMessage("array access out of bounds."); break; case X_DIVISION_BY_ZERO: AppendMessage("division by zero."); break; case X_BAD_SELF: AppendMessage("invalid self pointer."); break; case X_FORMAT_ERROR: AppendMessage("string format failed."); break; case X_OTHER: // no prepended message. break; default: { size_t len = strlen(m_Message); mysnprintf(m_Message + len, MAX_ERRORTEXT - len, "Unknown reason %d", reason); break; } } if (moreinfo != nullptr) { AppendMessage(" "); size_t len = strlen(m_Message); myvsnprintf(m_Message + len, MAX_ERRORTEXT - len, moreinfo, ap); } stacktrace = ""; }