Allow error message to be formatted

This commit is contained in:
SirLynix
2023-08-14 23:16:37 +02:00
committed by Jérôme Leclercq
parent 25957c4b7f
commit a741672a51
119 changed files with 707 additions and 490 deletions

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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();
}
}

View File

@@ -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;
}

View File

@@ -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)
{

View 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
}

View File

@@ -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;
}