8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-31 04:03:03 +01:00
firebird-mirror/src/common/fb_exception.cpp

298 lines
6.6 KiB
C++
Raw Normal View History

2003-02-17 14:28:17 +01:00
#include "firebird.h"
2014-09-29 13:03:47 +02:00
#include "firebird/Interface.h"
2002-11-11 19:06:01 +01:00
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include "gen/iberror.h"
#include "../common/classes/alloc.h"
#include "../common/classes/init.h"
#include "../common/classes/array.h"
#include "../common/ThreadStart.h"
2010-10-12 10:02:57 +02:00
#include "../common/utils_proto.h"
#include "../common/SimpleStatusVector.h"
#include "../common/StatusHolder.h"
namespace Firebird {
// ********************************* Exception *******************************
Exception::~Exception() throw() { }
void Exception::stuffException(DynamicStatusVector& status_vector) const throw()
{
StaticStatusVector status;
stuffException(status);
try
{
status_vector.save(status.begin());
}
2015-03-28 01:36:04 +01:00
catch (const BadAlloc&)
{
ISC_STATUS tmp[3];
processUnexpectedException(tmp);
status_vector.save(tmp);
}
}
void Exception::stuffException(CheckStatusWrapper* status_vector) const throw()
2010-10-12 10:02:57 +02:00
{
StaticStatusVector status;
stuffException(status);
fb_utils::setIStatus(status_vector, status.begin());
2010-10-12 10:02:57 +02:00
}
void Exception::processUnexpectedException(ISC_STATUS* vector) throw()
{
// do not use stuffException() here to avoid endless loop
try
{
throw;
}
2015-03-28 01:36:04 +01:00
catch (const BadAlloc&)
{
fb_utils::statusBadAlloc(vector);
}
2015-03-28 01:36:04 +01:00
catch (const Exception&)
{
fb_assert(false);
fb_utils::statusUnknown(vector);
}
}
2009-04-17 16:10:11 +02:00
// ********************************* status_exception *******************************
status_exception::status_exception() throw()
: m_status_vector(m_buffer)
2004-03-07 08:58:55 +01:00
{
fb_utils::init_status(m_status_vector);
}
status_exception::status_exception(const ISC_STATUS *status_vector) throw()
: m_status_vector(m_buffer)
2004-03-07 08:58:55 +01:00
{
fb_utils::init_status(m_status_vector);
if (status_vector)
{
set_status(status_vector);
}
}
2008-12-05 02:20:14 +01:00
status_exception::status_exception(const status_exception& from) throw()
: m_status_vector(m_buffer)
{
fb_utils::init_status(m_status_vector);
set_status(from.m_status_vector);
}
void status_exception::set_status(const ISC_STATUS *new_vector) throw()
2005-12-25 05:01:49 +01:00
{
fb_assert(new_vector != 0);
unsigned len = fb_utils::statusLength(new_vector);
2004-03-07 08:58:55 +01:00
try
{
if (len >= FB_NELEM(m_buffer))
{
m_status_vector = FB_NEW(*getDefaultMemoryPool()) ISC_STATUS[len + 1];
}
len = makeDynamicStrings(len, m_status_vector, new_vector);
m_status_vector[len] = isc_arg_end;
}
2015-03-28 01:36:04 +01:00
catch (const Exception&)
{
if (m_status_vector != m_buffer)
{
delete[] m_status_vector;
m_status_vector = m_buffer;
}
processUnexpectedException(m_buffer);
}
}
2008-12-05 02:20:14 +01:00
status_exception::~status_exception() throw()
{
2015-03-23 10:06:10 +01:00
delete[] findDynamicStrings(fb_utils::statusLength(m_status_vector), m_status_vector);
if (m_status_vector != m_buffer)
{
delete[] m_status_vector;
}
}
const char* status_exception::what() const throw()
2005-12-25 05:01:49 +01:00
{
return "Firebird::status_exception";
}
2008-12-05 02:20:14 +01:00
void status_exception::raise(const ISC_STATUS *status_vector)
2004-03-07 08:58:55 +01:00
{
throw status_exception(status_vector);
}
void status_exception::raise(const IStatus* status)
{
StaticStatusVector status_vector;
status_vector.mergeStatus(status);
throw status_exception(status_vector.begin());
}
void status_exception::raise(const Arg::StatusVector& statusVector)
2004-03-07 08:58:55 +01:00
{
throw status_exception(statusVector.value());
}
void status_exception::stuffByException(StaticStatusVector& status) const throw()
{
try
{
status.assign(m_status_vector, fb_utils::statusLength(m_status_vector) + 1);
}
2015-03-28 01:36:04 +01:00
catch (const BadAlloc&)
{
processUnexpectedException(status.makeEmergencyStatus());
}
}
2009-04-17 16:10:11 +02:00
// ********************************* BadAlloc ****************************
void BadAlloc::raise()
{
throw BadAlloc();
}
void BadAlloc::stuffByException(StaticStatusVector& status) const throw()
{
fb_utils::statusBadAlloc(status.makeEmergencyStatus());
}
const char* BadAlloc::what() const throw()
{
return "Firebird::BadAlloc";
}
2009-04-17 16:10:11 +02:00
// ********************************* LongJump ***************************
void LongJump::raise()
{
throw LongJump();
}
void LongJump::stuffByException(StaticStatusVector& status) const throw()
{
ISC_STATUS sv[] = {isc_arg_gds, isc_random, isc_arg_string,
(ISC_STATUS)(IPTR) "Unexpected call to Firebird::LongJump::stuffException()", isc_arg_end};
try
2010-10-12 10:02:57 +02:00
{
status.assign(sv, FB_NELEM(sv));
}
2015-03-28 01:36:04 +01:00
catch (const BadAlloc&)
{
processUnexpectedException(status.makeEmergencyStatus());
2010-10-12 10:02:57 +02:00
}
}
2009-07-23 02:56:28 +02:00
const char* LongJump::what() const throw()
{
return "Firebird::LongJump";
}
2009-04-17 16:10:11 +02:00
// ********************************* system_error ***************************
2008-12-05 02:20:14 +01:00
system_error::system_error(const char* syscall, int error_code) :
status_exception(), errorCode(error_code)
{
Arg::Gds temp(isc_sys_request);
temp << Arg::Str(syscall);
temp << SYS_ERR(errorCode);
set_status(temp.value());
}
void system_error::raise(const char* syscall, int error_code)
{
throw system_error(syscall, error_code);
}
void system_error::raise(const char* syscall)
{
throw system_error(syscall, getSystemError());
}
int system_error::getSystemError()
{
#ifdef WIN_NT
return GetLastError();
#else
return errno;
#endif
}
2009-04-17 16:10:11 +02:00
// ********************************* system_call_failed ***************************
2008-12-05 02:20:14 +01:00
system_call_failed::system_call_failed(const char* syscall, int error_code) :
system_error(syscall, error_code)
{
// NS: something unexpected has happened. Log the error to log file
// In the future we may consider terminating the process even in PROD_BUILD
2009-11-15 19:38:34 +01:00
gds__log("Operating system call %s failed. Error code %d", syscall, error_code);
2008-12-01 08:28:13 +01:00
#ifdef DEV_BUILD
2008-12-05 02:20:14 +01:00
// raised failed system call exception in DEV_BUILD in 99.99% means
// problems with the code - let's create memory dump now
abort();
#endif
}
void system_call_failed::raise(const char* syscall, int error_code)
2002-11-11 19:06:01 +01:00
{
throw system_call_failed(syscall, error_code);
2002-11-11 19:06:01 +01:00
}
void system_call_failed::raise(const char* syscall)
2002-11-11 19:06:01 +01:00
{
throw system_call_failed(syscall, getSystemError());
2002-11-11 19:06:01 +01:00
}
2009-04-17 16:10:11 +02:00
// ********************************* fatal_exception *******************************
fatal_exception::fatal_exception(const char* message) :
status_exception()
2002-11-11 19:06:01 +01:00
{
2009-02-03 12:02:00 +01:00
const ISC_STATUS temp[] =
{
2009-01-03 20:02:04 +01:00
isc_arg_gds,
isc_random,
2009-09-03 03:28:54 +02:00
isc_arg_string,
(ISC_STATUS)(IPTR) message,
2009-01-03 20:02:04 +01:00
isc_arg_end
};
set_status(temp);
2002-11-11 19:06:01 +01:00
}
// Keep in sync with the constructor above, please; "message" becomes 4th element
// after initialization of status vector in constructor.
const char* fatal_exception::what() const throw()
{
return reinterpret_cast<const char*>(value()[3]);
}
2003-12-31 06:36:12 +01:00
void fatal_exception::raise(const char* message)
2002-11-11 19:06:01 +01:00
{
throw fatal_exception(message);
}
void fatal_exception::raiseFmt(const char* format, ...)
{
va_list args;
va_start(args, format);
char buffer[1024];
VSNPRINTF(buffer, sizeof(buffer), format, args);
buffer[sizeof(buffer) - 1] = 0;
va_end(args);
throw fatal_exception(buffer);
}
2002-11-11 19:06:01 +01:00
} // namespace Firebird