Improved Error system

Former-commit-id: ddd08841d30575713f4a28ac02566f92791e5539
This commit is contained in:
Lynix 2013-09-25 09:29:25 +02:00
parent 672cbaed1d
commit a410e8856a
16 changed files with 199 additions and 51 deletions

View File

@ -25,6 +25,18 @@ enum nzEndianness
nzEndianness_Max = nzEndianness_LittleEndian
};
enum nzErrorFlag
{
nzErrorFlag_None = 0,
nzErrorFlag_Silent = 0x1,
nzErrorFlag_SilentDisabled = 0x2,
nzErrorFlag_ThrowException = 0x4,
nzErrorFlag_ThrowExceptionDisabled = 0x8,
nzErrorFlag_Max = nzErrorFlag_ThrowExceptionDisabled*2-1
};
enum nzErrorType
{
nzErrorType_AssertFailed,
@ -113,7 +125,7 @@ enum nzSphereType
enum nzStreamOptionFlags
{
nzStreamOption_None = 0x0,
nzStreamOption_None = 0,
nzStreamOption_Text = 0x1,

View File

@ -14,17 +14,37 @@
#include <Nazara/Core/String.hpp>
#if NAZARA_CORE_ENABLE_ASSERTS || defined(NAZARA_DEBUG)
#define NazaraAssert(a, err) if (!(a)) NzError(nzErrorType_AssertFailed, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION)
#define NazaraAssert(a, err) if (!(a)) NzError::Error(nzErrorType_AssertFailed, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION)
#else
#define NazaraAssert(a, err)
#endif
#define NazaraError(err) NzError(nzErrorType_Normal, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION)
#define NazaraInternalError(err) NzError(nzErrorType_Internal, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION)
#define NazaraWarning(err) NzError(nzErrorType_Warning, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION)
#define NazaraError(err) NzError::Error(nzErrorType_Normal, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION)
#define NazaraInternalError(err) NzError::Error(nzErrorType_Internal, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION)
#define NazaraWarning(err) NzError::Error(nzErrorType_Warning, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION)
NAZARA_API void NzError(nzErrorType type, const NzString& error, unsigned int line, const char* file, const char* function);
NAZARA_API unsigned int NzGetLastSystemErrorCode();
NAZARA_API NzString NzGetLastSystemError(unsigned int code = NzGetLastSystemErrorCode());
class NAZARA_API NzError
{
public:
NzError() = delete;
~NzError() = delete;
static void Error(nzErrorType type, const NzString& error);
static void Error(nzErrorType type, const NzString& error, unsigned int line, const char* file, const char* function);
static nzUInt32 GetFlags();
static NzString GetLastError(const char** file = nullptr, unsigned int* line = nullptr, const char** function = nullptr);
static unsigned int GetLastSystemErrorCode();
static NzString GetLastSystemError(unsigned int code = GetLastSystemErrorCode());
static void SetFlags(nzUInt32 flags);
private:
static nzUInt32 s_flags;
static NzString s_lastError;
static const char* s_lastErrorFunction;
static const char* s_lastErrorFile;
static unsigned int s_lastErrorLine;
};
#endif // NAZARA_ERROR_HPP

View File

@ -0,0 +1,28 @@
// Copyright (C) 2013 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_ERRORFLAGS_HPP
#define NAZARA_ERRORFLAGS_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Enums.hpp>
#include <Nazara/Core/NonCopyable.hpp>
class NzErrorFlags : NzNonCopyable
{
public:
NzErrorFlags(nzUInt32 flags, bool replace = false);
~NzErrorFlags();
nzUInt32 GetPreviousFlags() const;
void SetFlags(nzUInt32 flags, bool replace = false);
private:
nzUInt32 m_previousFlags;
};
#endif // NAZARA_ERRORFLAGS_HPP

View File

@ -43,6 +43,7 @@ class NAZARA_API NzLog : NzNonCopyable
void SetFile(const NzString& filePath);
void Write(const NzString& string);
void WriteError(nzErrorType type, const NzString& error);
void WriteError(nzErrorType type, const NzString& error, unsigned int line, const NzString& file, const NzString& func);
static NzLog* Instance();

View File

@ -5,6 +5,7 @@
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Log.hpp>
#include <cstdlib>
#include <stdexcept>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <windows.h>
@ -14,29 +15,76 @@
#include <Nazara/Core/Debug.hpp>
void NzError(nzErrorType type, const NzString& error, unsigned int line, const char* file, const char* function)
void NzError::Error(nzErrorType type, const NzString& error)
{
NazaraLog->WriteError(type, error, line, file, function);
if ((s_flags & nzErrorFlag_Silent) == 0 || (s_flags & nzErrorFlag_SilentDisabled) != 0)
NazaraLog->WriteError(type, error);
s_lastError = error;
s_lastErrorFile = "";
s_lastErrorFunction = "";
s_lastErrorLine = 0;
#if NAZARA_CORE_EXIT_ON_ASSERT_FAILURE
if (type == nzErrorType_AssertFailed)
std::exit(EXIT_FAILURE);
#endif
if ((s_flags & nzErrorFlag_ThrowException) != 0 && (s_flags & nzErrorFlag_ThrowExceptionDisabled) == 0)
throw std::runtime_error(error);
}
unsigned int NzGetLastSystemErrorCode()
void NzError::Error(nzErrorType type, const NzString& error, unsigned int line, const char* file, const char* function)
{
if ((s_flags & nzErrorFlag_Silent) == 0 || (s_flags & nzErrorFlag_SilentDisabled) != 0)
NazaraLog->WriteError(type, error, line, file, function);
s_lastError = error;
s_lastErrorFile = file;
s_lastErrorFunction = function;
s_lastErrorLine = line;
#if NAZARA_CORE_EXIT_ON_ASSERT_FAILURE
if (type == nzErrorType_AssertFailed)
std::exit(EXIT_FAILURE);
#endif
if ((s_flags & nzErrorFlag_ThrowException) != 0 && (s_flags & nzErrorFlag_ThrowExceptionDisabled) == 0)
throw std::runtime_error(error);
}
nzUInt32 NzError::GetFlags()
{
return s_flags;
}
NzString NzError::GetLastError(const char** file, unsigned int* line, const char** function)
{
if (file)
*file = s_lastErrorFile;
if (line)
*line = s_lastErrorLine;
if (function)
*function = s_lastErrorFunction;
return s_lastError;
}
unsigned int NzError::GetLastSystemErrorCode()
{
#if defined(NAZARA_PLATFORM_WINDOWS)
return GetLastError();
return ::GetLastError();
#elif defined(NAZARA_PLATFORM_POSIX)
return errno;
#else
#error GetLastSystemErrorCode is not implemented on this platform
#endif
return 0;
#endif
}
NzString NzGetLastSystemError(unsigned int code)
NzString NzError::GetLastSystemError(unsigned int code)
{
#if defined(NAZARA_PLATFORM_WINDOWS)
wchar_t* buffer = nullptr;
@ -60,6 +108,18 @@ NzString NzGetLastSystemError(unsigned int code)
#else
#error GetLastSystemError is not implemented on this platform
return "GetLastSystemError is not implemented on this platform";
return NzString("GetLastSystemError is not implemented on this platform");
#endif
}
void NzError::SetFlags(nzUInt32 flags)
{
s_flags = flags;
}
nzUInt32 NzError::s_flags = nzErrorFlag_None;
NzString NzError::s_lastError;
const char* NzError::s_lastErrorFunction = "";
const char* NzError::s_lastErrorFile = "";
unsigned int NzError::s_lastErrorLine = 0;

View File

@ -0,0 +1,31 @@
// Copyright (C) 2013 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Debug.hpp>
NzErrorFlags::NzErrorFlags(nzUInt32 flags, bool replace) :
m_previousFlags(NzError::GetFlags())
{
SetFlags(flags, replace);
}
NzErrorFlags::~NzErrorFlags()
{
NzError::SetFlags(m_previousFlags);
}
nzUInt32 NzErrorFlags::GetPreviousFlags() const
{
return m_previousFlags;
}
void NzErrorFlags::SetFlags(nzUInt32 flags, bool replace)
{
if (!replace)
flags |= m_previousFlags;
NzError::SetFlags(flags);
}

View File

@ -136,21 +136,17 @@ void NzLog::Write(const NzString& string)
}
}
void NzLog::WriteError(nzErrorType type, const NzString& error)
{
NzStringStream stream;
stream << errorType[type] << error;
Write(stream);
}
void NzLog::WriteError(nzErrorType type, const NzString& error, unsigned int line, const NzString& file, const NzString& func)
{
NzString stream;
stream.Reserve(std::strlen(errorType[type]) + error.GetSize() + 2 + file.GetSize() + 1 + NzGetNumberLength(line) +2 + func.GetSize() + 1);
stream += errorType[type];
stream += error;
stream += " (";
stream += file;
stream += ':';
stream += NzString::Number(line);
stream += ": ";
stream += func;
stream += ')';
/*NzStringStream stream;
stream << errorType[type] << error << " (" << file << ':' << line << ": " << func << ')';*/
NzStringStream stream;
stream << errorType[type] << error << " (" << file << ':' << line << ": " << func << ')';
Write(stream);
}

View File

@ -52,7 +52,7 @@ bool NzDirectoryImpl::NextResult()
else
{
if (GetLastError() != ERROR_NO_MORE_FILES)
NazaraError("Unable to get next result: " + NzGetLastSystemError());
NazaraError("Unable to get next result: " + NzError::GetLastSystemError());
return false;
}
@ -67,7 +67,7 @@ bool NzDirectoryImpl::Open(const NzString& dirPath)
if (m_handle == INVALID_HANDLE_VALUE)
{
NazaraError("Unable to open directory: " + NzGetLastSystemError());
NazaraError("Unable to open directory: " + NzError::GetLastSystemError());
return false;
}
@ -106,10 +106,10 @@ NzString NzDirectoryImpl::GetCurrent()
if (GetCurrentDirectoryW(size, path.get()) != 0)
currentPath = NzString::Unicode(path.get());
else
NazaraError("Unable to get current directory: " + NzGetLastSystemError());
NazaraError("Unable to get current directory: " + NzError::GetLastSystemError());
}
else if (size == 0)
NazaraError("Unable to get current directory: " + NzGetLastSystemError());
NazaraError("Unable to get current directory: " + NzError::GetLastSystemError());
else
currentPath = NzString::Unicode(path.get());

View File

@ -18,7 +18,7 @@ NzDynLibFunc NzDynLibImpl::GetSymbol(const NzString& symbol) const
{
NzDynLibFunc sym = reinterpret_cast<NzDynLibFunc>(GetProcAddress(m_handle, symbol.GetConstBuffer()));
if (!sym)
m_parent->SetLastError(NzGetLastSystemError());
m_parent->SetLastError(NzError::GetLastSystemError());
return sym;
}
@ -36,7 +36,7 @@ bool NzDynLibImpl::Load(const NzString& libraryPath)
return true;
else
{
m_parent->SetLastError(NzGetLastSystemError());
m_parent->SetLastError(NzError::GetLastSystemError());
return false;
}
}

View File

@ -38,7 +38,7 @@ bool NzFileImpl::EndOfFile() const
void NzFileImpl::Flush()
{
if (!FlushFileBuffers(m_handle))
NazaraError("Unable to flush file: " + NzGetLastSystemError());
NazaraError("Unable to flush file: " + NzError::GetLastSystemError());
}
nzUInt64 NzFileImpl::GetCursorPos() const
@ -191,7 +191,7 @@ bool NzFileImpl::Copy(const NzString& sourcePath, const NzString& targetPath)
return true;
else
{
NazaraError("Failed to copy file: " + NzGetLastSystemError());
NazaraError("Failed to copy file: " + NzError::GetLastSystemError());
return false;
}
@ -205,7 +205,7 @@ bool NzFileImpl::Delete(const NzString& filePath)
return true;
else
{
NazaraError("Failed to delete file (" + filePath + "): " + NzGetLastSystemError());
NazaraError("Failed to delete file (" + filePath + "): " + NzError::GetLastSystemError());
return false;
}
@ -235,7 +235,7 @@ time_t NzFileImpl::GetCreationTime(const NzString& filePath)
FILETIME creationTime;
if (!GetFileTime(handle, &creationTime, nullptr, nullptr))
{
NazaraError("Unable to get creation time: " + NzGetLastSystemError());
NazaraError("Unable to get creation time: " + NzError::GetLastSystemError());
CloseHandle(handle);
return 0;
@ -257,7 +257,7 @@ time_t NzFileImpl::GetLastAccessTime(const NzString& filePath)
FILETIME accessTime;
if (!GetFileTime(handle, nullptr, &accessTime, nullptr))
{
NazaraError("Unable to get last access time: " + NzGetLastSystemError());
NazaraError("Unable to get last access time: " + NzError::GetLastSystemError());
CloseHandle(handle);
return 0;
@ -279,7 +279,7 @@ time_t NzFileImpl::GetLastWriteTime(const NzString& filePath)
FILETIME writeTime;
if (!GetFileTime(handle, nullptr, nullptr, &writeTime))
{
NazaraError("Unable to get last write time: " + NzGetLastSystemError());
NazaraError("Unable to get last write time: " + NzError::GetLastSystemError());
CloseHandle(handle);
return 0;
@ -316,7 +316,7 @@ bool NzFileImpl::Rename(const NzString& sourcePath, const NzString& targetPath)
return true;
else
{
NazaraError("Unable to rename file: " + NzGetLastSystemError());
NazaraError("Unable to rename file: " + NzError::GetLastSystemError());
return false;
}
}

View File

@ -12,7 +12,7 @@ NzSemaphoreImpl::NzSemaphoreImpl(unsigned int count)
{
m_semaphore = CreateSemaphore(nullptr, count, std::numeric_limits<LONG>::max(), nullptr);
if (!m_semaphore)
NazaraError("Failed to create semaphore: " + NzGetLastSystemError());
NazaraError("Failed to create semaphore: " + NzError::GetLastSystemError());
}
NzSemaphoreImpl::~NzSemaphoreImpl()
@ -31,7 +31,7 @@ void NzSemaphoreImpl::Post()
{
#if NAZARA_CORE_SAFE
if (!ReleaseSemaphore(m_semaphore, 1, nullptr))
NazaraError("Failed to release semaphore: " + NzGetLastSystemError());
NazaraError("Failed to release semaphore: " + NzError::GetLastSystemError());
#else
ReleaseSemaphore(m_semaphore, 1, nullptr);
#endif
@ -41,7 +41,7 @@ void NzSemaphoreImpl::Wait()
{
#if NAZARA_CORE_SAFE
if (WaitForSingleObject(m_semaphore, INFINITE) == WAIT_FAILED)
NazaraError("Failed to wait for semaphore: " + NzGetLastSystemError());
NazaraError("Failed to wait for semaphore: " + NzError::GetLastSystemError());
#else
WaitForSingleObject(m_semaphore, INFINITE);
#endif
@ -53,7 +53,7 @@ bool NzSemaphoreImpl::Wait(nzUInt32 timeout)
DWORD result = WaitForSingleObject(m_semaphore, timeout);
if (result == WAIT_FAILED)
{
NazaraError("Failed to wait for semaphore: " + NzGetLastSystemError());
NazaraError("Failed to wait for semaphore: " + NzError::GetLastSystemError());
return false;
}
else

View File

@ -12,7 +12,7 @@ NzThreadImpl::NzThreadImpl(NzFunctor* functor)
{
m_handle = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, &NzThreadImpl::ThreadProc, functor, 0, nullptr));
if (!m_handle)
NazaraInternalError("Failed to create thread: " + NzGetLastSystemError());
NazaraInternalError("Failed to create thread: " + NzError::GetLastSystemError());
}
void NzThreadImpl::Detach()

View File

@ -118,7 +118,7 @@ const NzShaderProgram* NzShaderProgramManager::Get(const NzShaderProgramManagerP
if (shaderFile.Read(&binary[0], size) != size)
{
NazaraError("Failed to read program binary");
return false;
return nullptr;
}
shaderFile.Close();
@ -148,7 +148,7 @@ const NzShaderProgram* NzShaderProgramManager::Get(const NzShaderProgramManagerP
if (!programBinary.IsEmpty())
{
if (!shaderFile.Open(NzFile::Truncate | NzFile::WriteOnly) || !shaderFile.Write(programBinary))
NazaraWarning("Failed to save program binary to file \"" + programFileName + "\": " + NzGetLastSystemError());
NazaraWarning("Failed to save program binary to file \"" + programFileName + '"');
}
else
NazaraWarning("Failed to retrieve shader program binary");

View File

@ -184,7 +184,7 @@ bool NzContextImpl::Create(NzContextParameters& parameters)
NzLockGuard lock(mutex);
if (!wglShareLists(shareContext, m_context))
NazaraWarning("Failed to share the context: " + NzGetLastSystemError());
NazaraWarning("Failed to share the context: " + NzError::GetLastSystemError());
}
}

View File

@ -34,7 +34,7 @@ bool NzCursorImpl::Create(const NzImage& cursor, int hotSpotX, int hotSpotY)
if (!m_cursor)
{
NazaraError("Failed to create cursor: " + NzGetLastSystemError());
NazaraError("Failed to create cursor: " + NzError::GetLastSystemError());
return false;
}

View File

@ -31,7 +31,7 @@ bool NzIconImpl::Create(const NzImage& icon)
if (!m_icon)
{
NazaraError("Failed to create icon: " + NzGetLastSystemError());
NazaraError("Failed to create icon: " + NzError::GetLastSystemError());
return false;
}