138 lines
3.8 KiB
C++
138 lines
3.8 KiB
C++
// Copyright (C) 2007 EQ2EMulator Development Team, GPL v3
|
|
|
|
#pragma once
|
|
|
|
#include <vector>
|
|
#include <string>
|
|
#include <mutex>
|
|
#include <iostream>
|
|
#include <memory>
|
|
#include <algorithm>
|
|
#include <cstdio>
|
|
|
|
#include "types.hpp"
|
|
|
|
enum eEQEMuError
|
|
{
|
|
EQEMuError_NoError,
|
|
EQEMuError_Mysql_1405,
|
|
EQEMuError_Mysql_2003,
|
|
EQEMuError_Mysql_2005,
|
|
EQEMuError_Mysql_2007,
|
|
EQEMuError_MaxErrorID
|
|
};
|
|
|
|
// Error message lookup table for predefined error codes
|
|
const char* EQEMuErrorText[EQEMuError_MaxErrorID] = {
|
|
"ErrorID# 0, No Error",
|
|
"MySQL Error #1405 or #2001 means your mysql server rejected the username and password you presented it.",
|
|
"MySQL Error #2003 means you were unable to connect to the mysql server.",
|
|
"MySQL Error #2005 means you there are too many connections on the mysql server. The server is overloaded.",
|
|
"MySQL Error #2007 means you the server is out of memory. The server is overloaded.",
|
|
};
|
|
|
|
// Error storage structure to handle both enum and string errors
|
|
struct ErrorEntry
|
|
{
|
|
bool is_enum_error; // True if this is an enum error, false for string error
|
|
int32 error_id; // Used only for enum errors
|
|
std::string message; // Used for string errors or can store enum converted to string
|
|
|
|
ErrorEntry(eEQEMuError error) : is_enum_error(true), error_id(error) {}
|
|
ErrorEntry(const std::string& msg) : is_enum_error(false), error_id(0), message(msg) {}
|
|
};
|
|
|
|
// Global error list and mutex for thread-safe error collection
|
|
std::vector<ErrorEntry> g_error_list;
|
|
std::mutex g_error_mutex;
|
|
|
|
// Forward declaration for signal handling
|
|
void CatchSignal(int sig_num);
|
|
|
|
// Retrieves the error text for a given error ID
|
|
// Returns the corresponding error message or out of range message
|
|
const char* GetErrorText(int32 iError)
|
|
{
|
|
if (iError >= EQEMuError_MaxErrorID)
|
|
return "ErrorID# out of range";
|
|
else
|
|
return EQEMuErrorText[iError];
|
|
}
|
|
|
|
// Adds an enumerated error to the error list with optional immediate exit
|
|
// Checks for duplicate enum errors before adding to prevent spam
|
|
void AddEQEMuError(eEQEMuError iError, bool iExitNow = false)
|
|
{
|
|
if (!iError)
|
|
return;
|
|
|
|
std::lock_guard<std::mutex> lock(g_error_mutex);
|
|
|
|
// Check for duplicate enum errors
|
|
auto it = std::find_if(g_error_list.begin(), g_error_list.end(),
|
|
[iError](const ErrorEntry& entry) {
|
|
return entry.is_enum_error && entry.error_id == iError;
|
|
});
|
|
|
|
if (it != g_error_list.end())
|
|
return; // Duplicate found, don't add
|
|
|
|
g_error_list.emplace_back(iError);
|
|
|
|
if (iExitNow)
|
|
CatchSignal(2);
|
|
}
|
|
|
|
// Adds a string-based error to the error list with optional immediate exit
|
|
// String errors are not deduplicated as they may contain unique information
|
|
void AddEQEMuError(const char* iError, bool iExitNow = false)
|
|
{
|
|
if (!iError)
|
|
return;
|
|
|
|
std::lock_guard<std::mutex> lock(g_error_mutex);
|
|
g_error_list.emplace_back(std::string(iError));
|
|
|
|
if (iExitNow)
|
|
CatchSignal(2);
|
|
}
|
|
|
|
// Checks and displays all accumulated errors, then clears the error list
|
|
// Returns the number of errors that were found and displayed
|
|
int32 CheckEQEMuError()
|
|
{
|
|
std::lock_guard<std::mutex> lock(g_error_mutex);
|
|
|
|
if (g_error_list.empty())
|
|
return 0;
|
|
|
|
bool header_printed = false;
|
|
int32 error_count = 0;
|
|
|
|
for (const auto& entry : g_error_list) {
|
|
if (!header_printed) {
|
|
std::fprintf(stdout, "===============================\nRuntime errors:\n\n");
|
|
header_printed = true;
|
|
}
|
|
|
|
if (entry.is_enum_error) {
|
|
std::fprintf(stdout, "%s\n", GetErrorText(entry.error_id));
|
|
} else {
|
|
std::fprintf(stdout, "%s\n\n", entry.message.c_str());
|
|
}
|
|
error_count++;
|
|
}
|
|
|
|
g_error_list.clear();
|
|
return error_count;
|
|
}
|
|
|
|
// Checks for errors and pauses for user input if any errors were found
|
|
// Useful for keeping console windows open to display error messages
|
|
void CheckEQEMuErrorAndPause()
|
|
{
|
|
if (CheckEQEMuError()) {
|
|
std::fprintf(stdout, "Hit any key to exit\n");
|
|
std::getchar();
|
|
}
|
|
} |