diff --git a/apps/openmw-mp/Script/CommandController.cpp b/apps/openmw-mp/Script/CommandController.cpp index 00a4c0d7c..22c095ae2 100644 --- a/apps/openmw-mp/Script/CommandController.cpp +++ b/apps/openmw-mp/Script/CommandController.cpp @@ -93,10 +93,10 @@ std::deque CommandController::cmdParser(const std::string &message) /*auto const command = '/' >> *~x3::char_(sep) >> sep; if (!x3::phrase_parse(message.cbegin(), message.cend(), arguments, command, ret)) - throw runtime_error("failed to parse message: "+ message);*/ + Utils::throwError("failed to parse message: "+ message);*/ if (!x3::parse(message.cbegin(), message.cend(), arguments, ret)) - throw runtime_error("failed to parse message: " + message); + Utils::throwError("failed to parse message: " + message); return ret; } diff --git a/apps/openmw-mp/Script/EventController.cpp b/apps/openmw-mp/Script/EventController.cpp index a87578894..e8b630e09 100644 --- a/apps/openmw-mp/Script/EventController.cpp +++ b/apps/openmw-mp/Script/EventController.cpp @@ -100,7 +100,7 @@ EventController::EventController(LuaState *luaCtrl) }); if (!found) - throw runtime_error("Event " + to_string(i) + " is not registered. Dear developer, please fix me :D"); + Utils::throwError("Event " + to_string(i) + " is not registered"); #endif events[i]; // create core event } diff --git a/apps/openmw-mp/Script/LuaState.cpp b/apps/openmw-mp/Script/LuaState.cpp index fbaef79fc..035f93b82 100644 --- a/apps/openmw-mp/Script/LuaState.cpp +++ b/apps/openmw-mp/Script/LuaState.cpp @@ -406,7 +406,7 @@ void checkDependencies(const vector &modules, const ServerModu sstr << depNameRequest << ": version \"" << depVersionFound << "\" is not applicable for \"" << smi.name << "\" expected \"" << depVersionRequest + "\""; if (fatal) - throw runtime_error(sstr.str()); + Utils::throwError(sstr.str()); else LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "%s", sstr.str().c_str()); } @@ -416,7 +416,7 @@ void checkDependencies(const vector &modules, const ServerModu stringstream sstr; sstr << depNameRequest + " \"" << depVersionRequest << "\" not found."; if (fatal) - throw runtime_error(sstr.str()); + Utils::throwError(sstr.str()); else LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "%s", sstr.str().c_str()); } @@ -468,7 +468,7 @@ vector::iterator> loadOrderSolver(vectorname << "\" and \"" << (*found)->name << "\" depend on each other" << endl; - throw runtime_error(sstr.str()); + Utils::throwError(sstr.str()); } } @@ -497,7 +497,7 @@ void LuaState::loadModules(const std::string &moduleDir, std::vector Utils::split(const string &str, int delimiter) { string buffer; @@ -52,3 +54,20 @@ ESM::Cell Utils::getCellFromDescription(std::string cellDescription) return cell; } + +const std::string Utils::getLastError() +{ + return lastErrorMessage; +} + +void Utils::throwError(const std::string errorMessage) +{ +#ifdef _WIN32 + // Throwing exceptions makes them show up as "bad exception" on Windows with + // our stacktracer, so record their intended error messages separately here + // when possible + lastErrorMessage = errorMessage; +#endif + + throw runtime_error(errorMessage); +} diff --git a/apps/openmw-mp/Utils.hpp b/apps/openmw-mp/Utils.hpp index 6d4713e1d..b6aaedc75 100644 --- a/apps/openmw-mp/Utils.hpp +++ b/apps/openmw-mp/Utils.hpp @@ -40,6 +40,10 @@ namespace Utils ESM::Cell getCellFromDescription(std::string cellDescription); + const std::string getLastError(); + + void throwError(std::string errorMessage); + template constexpr unsigned int hash(const char(&str)[N], size_t I = N) { diff --git a/apps/openmw-mp/main.cpp b/apps/openmw-mp/main.cpp index ea3a9aecf..ec37cfe05 100644 --- a/apps/openmw-mp/main.cpp +++ b/apps/openmw-mp/main.cpp @@ -151,7 +151,13 @@ int main(int argc, char *argv[]) } catch (const exception &e) { - LOG_MESSAGE_SIMPLE(Log::LOG_FATAL, " Woops, something wrong! Exception:\n\t%s", e.what()); + LOG_MESSAGE_SIMPLE(Log::LOG_FATAL, "A fatal error has occurred!"); + +#ifndef _WIN32 + LOG_APPEND(Log::LOG_FATAL, "\t%s", e.what()); +#else + LOG_APPEND(Log::LOG_FATAL, "\t%s", Utils::getLastError().c_str()); +#endif } stacktrace(); @@ -232,21 +238,21 @@ int main(int argc, char *argv[]) case RakNet::RAKNET_STARTED: break; case RakNet::RAKNET_ALREADY_STARTED: - throw runtime_error("Already started"); + Utils::throwError("Already started"); case RakNet::INVALID_SOCKET_DESCRIPTORS: - throw runtime_error("Incorrect port or address"); + Utils::throwError("Incorrect port or address"); case RakNet::INVALID_MAX_CONNECTIONS: - throw runtime_error("Max players cannot be negative or 0"); + Utils::throwError("Max players cannot be negative or 0"); case RakNet::SOCKET_FAILED_TO_BIND: case RakNet::SOCKET_PORT_ALREADY_IN_USE: case RakNet::PORT_CANNOT_BE_ZERO: - throw runtime_error("Failed to bind port"); + Utils::throwError("Failed to bind port"); case RakNet::SOCKET_FAILED_TEST_SEND: case RakNet::SOCKET_FAMILY_NOT_SUPPORTED: case RakNet::FAILED_TO_CREATE_NETWORK_THREAD: case RakNet::COULD_NOT_GENERATE_GUID: case RakNet::STARTUP_OTHER_FAILURE: - throw runtime_error("Cannot start server"); + Utils::throwError("Cannot start server"); } peer->SetMaximumIncomingConnections((unsigned short) (players));