Allow error message to be formatted
This commit is contained in:
committed by
Jérôme Leclercq
parent
25957c4b7f
commit
a741672a51
@@ -76,7 +76,7 @@ namespace Nz
|
||||
return std::make_unique<WhirlpoolHasher>();
|
||||
}
|
||||
|
||||
NazaraInternalError("Hash type not handled (0x" + NumberToString(UnderlyingCast(type), 16) + ')');
|
||||
NazaraInternalError("Hash type not handled ({0:#x})", UnderlyingCast(type));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Nz
|
||||
auto impl = std::make_unique<DynLibImpl>();
|
||||
if (!impl->Load(libraryPath, &m_lastError))
|
||||
{
|
||||
NazaraError("Failed to load library: " + m_lastError);
|
||||
NazaraError("failed to load library: {0}", m_lastError);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Core/StringExt.hpp>
|
||||
#include <NazaraUtils/CallOnExit.hpp>
|
||||
#include <NazaraUtils/EnumArray.hpp>
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -20,6 +21,22 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
namespace NAZARA_ANONYMOUS_NAMESPACE
|
||||
{
|
||||
constexpr EnumArray<ErrorType, std::string_view> s_errorTypes = {
|
||||
"Assert failed: ", // ErrorType::AssertFailed
|
||||
"Internal error: ", // ErrorType::Internal
|
||||
"Error: ", // ErrorType::Normal
|
||||
"Warning: " // ErrorType::Warning
|
||||
};
|
||||
|
||||
thread_local ErrorModeFlags s_flags;
|
||||
thread_local std::string s_lastError = "no error";
|
||||
thread_local std::string_view s_lastErrorFunction;
|
||||
thread_local std::string_view s_lastErrorFile;
|
||||
thread_local unsigned int s_lastErrorLine = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup core
|
||||
* \class Nz::Error
|
||||
@@ -33,6 +50,8 @@ namespace Nz
|
||||
|
||||
ErrorModeFlags Error::GetFlags()
|
||||
{
|
||||
NAZARA_USE_ANONYMOUS_NAMESPACE
|
||||
|
||||
return s_flags;
|
||||
}
|
||||
|
||||
@@ -45,8 +64,10 @@ namespace Nz
|
||||
* \param function Optional argument to set last error function
|
||||
*/
|
||||
|
||||
std::string Error::GetLastError(const char** file, unsigned int* line, const char** function)
|
||||
std::string Error::GetLastError(std::string_view* file, unsigned int* line, std::string_view* function)
|
||||
{
|
||||
NAZARA_USE_ANONYMOUS_NAMESPACE
|
||||
|
||||
if (file)
|
||||
*file = s_lastErrorFile;
|
||||
|
||||
@@ -118,90 +139,39 @@ namespace Nz
|
||||
|
||||
void Error::SetFlags(ErrorModeFlags flags)
|
||||
{
|
||||
NAZARA_USE_ANONYMOUS_NAMESPACE
|
||||
|
||||
s_flags = flags;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks if the error should trigger
|
||||
*
|
||||
* \param type ErrorType of the error
|
||||
* \param error Message of the error
|
||||
*
|
||||
* \remark Produces a std::abort on AssertFailed with NAZARA_CORE_EXIT_ON_ASSERT_FAILURE defined
|
||||
* \remark Produces a std::runtime_error on AssertFailed or throwing exception
|
||||
*/
|
||||
|
||||
void Error::Trigger(ErrorType type, std::string error)
|
||||
void Error::TriggerInternal(ErrorType type, std::string error, unsigned int line, std::string_view file, std::string_view function)
|
||||
{
|
||||
if (type == ErrorType::AssertFailed || (s_flags & ErrorMode::Silent) == 0 || (s_flags & ErrorMode::SilentDisabled) != 0)
|
||||
Log::WriteError(type, error);
|
||||
NAZARA_USE_ANONYMOUS_NAMESPACE
|
||||
|
||||
s_lastError = std::move(error);
|
||||
s_lastErrorFile = "";
|
||||
s_lastErrorFunction = "";
|
||||
s_lastErrorLine = 0;
|
||||
if (type == ErrorType::AssertFailed || (s_flags & ErrorMode::Silent) == 0)
|
||||
{
|
||||
if (line == 0 && file.empty())
|
||||
Log::Write("{}{}", s_errorTypes[type], error);
|
||||
else
|
||||
Log::Write("{}{} ({}:{}: {})", s_errorTypes[type], error, file, line, function);
|
||||
}
|
||||
|
||||
if (type != ErrorType::Warning)
|
||||
{
|
||||
s_lastError = std::move(error);
|
||||
s_lastErrorFile = file;
|
||||
s_lastErrorFunction = function;
|
||||
s_lastErrorLine = line;
|
||||
}
|
||||
|
||||
#if NAZARA_CORE_EXIT_ON_ASSERT_FAILURE
|
||||
if (type == ErrorType::AssertFailed)
|
||||
std::abort();
|
||||
#endif
|
||||
|
||||
if (type == ErrorType::AssertFailed || (type != ErrorType::Warning &&
|
||||
(s_flags & ErrorMode::ThrowException) != 0 && (s_flags & ErrorMode::ThrowExceptionDisabled) == 0))
|
||||
if (type == ErrorType::AssertFailed || (type != ErrorType::Warning && s_flags.Test(ErrorMode::ThrowException)))
|
||||
throw std::runtime_error(s_lastError);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks if the error should trigger
|
||||
*
|
||||
* \param type ErrorType of the error
|
||||
* \param error Message of the error
|
||||
* \param line Line of the error
|
||||
* \param file File of the error
|
||||
* \param function Function of the error
|
||||
*
|
||||
* \remark Produces a std::abort on AssertFailed with NAZARA_CORE_EXIT_ON_ASSERT_FAILURE defined
|
||||
* \remark Produces a std::runtime_error on AssertFailed or throwing exception
|
||||
*/
|
||||
|
||||
void Error::Trigger(ErrorType type, std::string error, unsigned int line, const char* file, const char* function)
|
||||
{
|
||||
file = GetCurrentFileRelativeToEngine(file);
|
||||
|
||||
if (type == ErrorType::AssertFailed || (s_flags & ErrorMode::Silent) == 0 || (s_flags & ErrorMode::SilentDisabled) != 0)
|
||||
Log::WriteError(type, error, line, file, function);
|
||||
|
||||
s_lastError = std::move(error);
|
||||
s_lastErrorFile = file;
|
||||
s_lastErrorFunction = function;
|
||||
s_lastErrorLine = line;
|
||||
|
||||
#if NAZARA_CORE_EXIT_ON_ASSERT_FAILURE
|
||||
if (type == ErrorType::AssertFailed)
|
||||
std::abort();
|
||||
#endif
|
||||
|
||||
if (type == ErrorType::AssertFailed || (type != ErrorType::Warning &&
|
||||
(s_flags & ErrorMode::ThrowException) != 0 && (s_flags & ErrorMode::ThrowExceptionDisabled) == 0))
|
||||
throw std::runtime_error(s_lastError);
|
||||
}
|
||||
|
||||
const char* Error::GetCurrentFileRelativeToEngine(const char* file)
|
||||
{
|
||||
if (const char* ptr = std::strstr(file, "NazaraEngine/"))
|
||||
return ptr;
|
||||
|
||||
if (const char* ptr = std::strstr(file, "NazaraEngine\\"))
|
||||
return ptr;
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
ErrorModeFlags Error::s_flags = ErrorMode::None;
|
||||
std::string Error::s_lastError;
|
||||
const char* Error::s_lastErrorFunction = "";
|
||||
const char* Error::s_lastErrorFile = "";
|
||||
unsigned int Error::s_lastErrorLine = 0;
|
||||
}
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
|
||||
@@ -21,10 +21,10 @@ namespace Nz
|
||||
* \param replace Replace the entirely the old flag if true, else do a "OR"
|
||||
*/
|
||||
|
||||
ErrorFlags::ErrorFlags(ErrorModeFlags flags, bool replace) :
|
||||
ErrorFlags::ErrorFlags(ErrorModeFlags orFlags, ErrorModeFlags andFlags) :
|
||||
m_previousFlags(Error::GetFlags())
|
||||
{
|
||||
SetFlags(flags, replace);
|
||||
SetFlags(orFlags, andFlags);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -51,11 +51,12 @@ namespace Nz
|
||||
* \param flags Flags for the error
|
||||
* \param replace Replace the entirely the old flag if true, else do a "OR"
|
||||
*/
|
||||
void ErrorFlags::SetFlags(ErrorModeFlags flags, bool replace)
|
||||
void ErrorFlags::SetFlags(ErrorModeFlags orFlags, ErrorModeFlags andFlags)
|
||||
{
|
||||
if (!replace)
|
||||
flags |= m_previousFlags;
|
||||
ErrorModeFlags newFlags = m_previousFlags;
|
||||
newFlags |= orFlags;
|
||||
newFlags &= andFlags;
|
||||
|
||||
Error::SetFlags(flags);
|
||||
Error::SetFlags(newFlags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ namespace Nz
|
||||
if (!impl->Open(m_filePath, openMode))
|
||||
{
|
||||
ErrorFlags flags(ErrorMode::Silent); // Silent by default
|
||||
NazaraError("failed to open \"" + m_filePath.generic_u8string() + "\": " + Error::GetLastSystemError());
|
||||
NazaraError("failed to open \"{0}\": {1}", m_filePath, Error::GetLastSystemError());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ namespace Nz
|
||||
std::unique_ptr<FileImpl> impl = std::make_unique<FileImpl>(this);
|
||||
if (!impl->Open(filePath, m_openMode))
|
||||
{
|
||||
NazaraError("Failed to open new file; " + Error::GetLastSystemError());
|
||||
NazaraError("failed to open new file; {0}", Error::GetLastSystemError());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ namespace Nz
|
||||
File file(path);
|
||||
if (!file.Open(OpenMode::ReadOnly | OpenMode::Unbuffered)) //< unbuffered since we will read all the file at once
|
||||
{
|
||||
NazaraError("failed to open \"" + path.generic_u8string() + '"');
|
||||
NazaraError("failed to open \"{0}\"", path);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ namespace Nz
|
||||
File file(path);
|
||||
if (!file.Open(OpenMode::WriteOnly | OpenMode::Unbuffered)) //< unbuffered since we will write all the file at once
|
||||
{
|
||||
NazaraError("failed to open \"" + path.generic_u8string() + '"');
|
||||
NazaraError("failed to open \"{0}\"", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -613,7 +613,7 @@ namespace Nz
|
||||
break;
|
||||
|
||||
default:
|
||||
NazaraError("Split heuristic out of enum (0x" + NumberToString(method, 16) + ')');
|
||||
NazaraError("Split heuristic out of enum ({0:#x})", UnderlyingCast(method));
|
||||
splitHorizontal = true;
|
||||
}
|
||||
|
||||
@@ -658,7 +658,7 @@ namespace Nz
|
||||
return ScoreWorstShortSideFit(width, height, freeRect);
|
||||
}
|
||||
|
||||
NazaraError("Rect choice heuristic out of enum (0x" + NumberToString(rectChoice, 16) + ')');
|
||||
NazaraError("Rect choice heuristic out of enum ({0:#x})", UnderlyingCast(rectChoice));
|
||||
return std::numeric_limits<int>::max();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Nz
|
||||
void FileImpl::Flush()
|
||||
{
|
||||
if (fsync(m_fileDescriptor) == -1)
|
||||
NazaraError("Unable to flush file: " + Error::GetLastSystemError());
|
||||
NazaraError("Unable to flush file: {0}", Error::GetLastSystemError());
|
||||
}
|
||||
|
||||
UInt64 FileImpl::GetCursorPos() const
|
||||
@@ -81,7 +81,7 @@ namespace Nz
|
||||
int fileDescriptor = Open_def(filePath.generic_u8string().data(), flags, permissions);
|
||||
if (fileDescriptor == -1)
|
||||
{
|
||||
NazaraError("Failed to open \"" + filePath.generic_u8string() + "\" : " + Error::GetLastSystemError());
|
||||
NazaraError("Failed to open \"{0}\": {1}", filePath, Error::GetLastSystemError());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ namespace Nz
|
||||
break;
|
||||
|
||||
default:
|
||||
NazaraInternalError("Cursor position not handled (0x" + NumberToString(UnderlyingCast(pos), 16) + ')');
|
||||
NazaraInternalError("Cursor position not handled ({0:#x})", UnderlyingCast(pos));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -202,7 +202,7 @@ namespace Nz
|
||||
}
|
||||
catch (utf8::exception& e)
|
||||
{
|
||||
NazaraError("UTF-8 error: " + std::string(e.what()));
|
||||
NazaraError("UTF-8 error: {0}", e.what());
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
||||
61
src/Nazara/Core/ToString.cpp
Normal file
61
src/Nazara/Core/ToString.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// 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/ToString.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/std.h>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
namespace Detail
|
||||
{
|
||||
std::string FormatFallback(std::string_view str)
|
||||
{
|
||||
return fmt::format(str);
|
||||
}
|
||||
|
||||
std::string FormatFallback(std::string_view str, std::string_view param1)
|
||||
{
|
||||
return fmt::format(str, param1);
|
||||
}
|
||||
|
||||
std::string FormatFallback(std::string_view str, std::string_view param1, std::string_view param2)
|
||||
{
|
||||
return fmt::format(str, param1, param2);
|
||||
}
|
||||
|
||||
std::string FormatFallback(std::string_view str, std::string_view param1, std::string_view param2, std::string_view param3)
|
||||
{
|
||||
return fmt::format(str, param1, param2, param3);
|
||||
}
|
||||
|
||||
std::string FormatFallback(std::string_view str, std::string_view param1, std::string_view param2, std::string_view param3, std::string_view param4)
|
||||
{
|
||||
return fmt::format(str, param1, param2, param3, param4);
|
||||
}
|
||||
|
||||
std::string FormatFallback(std::string_view str, std::string_view param1, std::string_view param2, std::string_view param3, std::string_view param4, std::string_view param5)
|
||||
{
|
||||
return fmt::format(str, param1, param2, param3, param4, param5);
|
||||
}
|
||||
}
|
||||
|
||||
std::string ToStringFormatter<std::filesystem::path>::Format(const std::filesystem::path& path)
|
||||
{
|
||||
return path.generic_u8string();
|
||||
}
|
||||
|
||||
#define NAZARA_TO_STRING_FMT_SPEC(Type) \
|
||||
std::string ToStringFormatter<Type>::Format(Type value) \
|
||||
{ \
|
||||
return fmt::format("{}", value); \
|
||||
}
|
||||
|
||||
NAZARA_TO_STRING_FMT_SPEC(float);
|
||||
NAZARA_TO_STRING_FMT_SPEC(double);
|
||||
NAZARA_TO_STRING_FMT_SPEC(long double);
|
||||
|
||||
#undef NAZARA_TO_STRING_CPP_SPEC
|
||||
}
|
||||
@@ -43,7 +43,7 @@ namespace Nz
|
||||
void FileImpl::Flush()
|
||||
{
|
||||
if (!FlushFileBuffers(m_handle))
|
||||
NazaraError("Unable to flush file: " + Error::GetLastSystemError());
|
||||
NazaraError("Unable to flush file: {0}", Error::GetLastSystemError());
|
||||
}
|
||||
|
||||
UInt64 FileImpl::GetCursorPos() const
|
||||
@@ -153,7 +153,7 @@ namespace Nz
|
||||
break;
|
||||
|
||||
default:
|
||||
NazaraInternalError("Cursor position not handled (0x" + NumberToString(UnderlyingCast(pos), 16) + ')');
|
||||
NazaraInternalError("Cursor position not handled ({0:#x})", UnderlyingCast(pos));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -177,13 +177,13 @@ namespace Nz
|
||||
|
||||
if (!SetCursorPos(CursorPosition::AtBegin, size))
|
||||
{
|
||||
NazaraError("Failed to set file size: failed to move cursor position: " + Error::GetLastSystemError());
|
||||
NazaraError("failed to set file size: failed to move cursor position: {0}", Error::GetLastSystemError());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetEndOfFile(m_handle))
|
||||
{
|
||||
NazaraError("Failed to set file size: " + Error::GetLastSystemError());
|
||||
NazaraError("failed to set file size: {0}", Error::GetLastSystemError());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user