Skip to content

Commit

Permalink
fix(skymp5-server): fix mp.callPapyrusFunction error handling (#2045)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pospelove authored Jun 28, 2024
1 parent 63e9d0b commit 726b84d
Showing 1 changed file with 21 additions and 3 deletions.
24 changes: 21 additions & 3 deletions skymp5-server/cpp/addon/ScampServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,12 @@ Napi::Value ScampServer::GetIdFromDesc(const Napi::CallbackInfo& info)

Napi::Value ScampServer::CallPapyrusFunction(const Napi::CallbackInfo& info)
{
// This function throws exceptions in case of bad input
// But it also catches exceptions from the Papyrus VM functions
// This is because
// 1) they're rare and unexpected, and we don't want to crash the sever
// 2) in Papyrus (not JS) we catch them all. so it's consistent
// 3) we plan replacing all exceptions with logs in Papyrus VM functions
try {
auto callType = NapiHelper::ExtractString(info[0], "callType");
auto className = NapiHelper::ExtractString(info[1], "className");
Expand All @@ -1045,15 +1051,27 @@ Napi::Value ScampServer::CallPapyrusFunction(const Napi::CallbackInfo& info)
auto& vm = partOne->worldState.GetPapyrusVm();
if (callType == "method") {
if (self.GetType() == VarValue::Type::kType_Object) {
res = vm.CallMethod(static_cast<IGameObject*>(self),
functionName.data(), args);
try {
res = vm.CallMethod(static_cast<IGameObject*>(self),
functionName.data(), args);
} catch (std::exception& e) {
res = VarValue::None();
spdlog::error("ScampServer::CallPapyrusFunction {} {} - {}",
self.ToString(), functionName, e.what());
}
} else {
throw std::runtime_error(
"Can't call Papyrus method on non-object self '" + self.ToString() +
"'");
}
} else if (callType == "global") {
res = vm.CallStatic(className, functionName, args);
try {
res = vm.CallStatic(className, functionName, args);
} catch (std::exception& e) {
res = VarValue::None();
spdlog::error("ScampServer::CallPapyrusFunction {} {} - {}", className,
functionName, e.what());
}
} else {
throw std::runtime_error("Unknown call type '" + callType +
"', expected one of ['method', 'global']");
Expand Down

0 comments on commit 726b84d

Please sign in to comment.