Send structured server errors to papyrus

Refactored error handling, but I still haven't tested it in-game.
This commit is contained in:
Tyler Hallada 2021-02-28 18:51:24 -05:00
parent ea3cf72c3c
commit 7c77bc47be
6 changed files with 161 additions and 70 deletions

View File

@ -28,7 +28,7 @@ void StatusCheckImpl(RE::BSFixedString api_url, RE::TESQuest* quest) {
SKSE::RegistrationMap<bool> successReg = SKSE::RegistrationMap<bool>(); SKSE::RegistrationMap<bool> successReg = SKSE::RegistrationMap<bool>();
successReg.Register(quest, RE::BSFixedString("OnStatusCheckSuccess")); successReg.Register(quest, RE::BSFixedString("OnStatusCheckSuccess"));
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>(); SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg = SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString>();
failReg.Register(quest, RE::BSFixedString("OnStatusCheckFail")); failReg.Register(quest, RE::BSFixedString("OnStatusCheckFail"));
logger::info(FMT_STRING("StatusCheck api_url: {}"), api_url); logger::info(FMT_STRING("StatusCheck api_url: {}"), api_url);
@ -38,9 +38,16 @@ void StatusCheckImpl(RE::BSFixedString api_url, RE::TESQuest* quest) {
logger::info(FMT_STRING("StatusCheck success: {}"), success); logger::info(FMT_STRING("StatusCheck success: {}"), success);
successReg.SendEvent(success); successReg.SendEvent(success);
} else { } else {
const char* error = result.AsErr(); FFIError error = result.AsErr();
logger::error(FMT_STRING("StatusCheck failure: {}"), error); if (error.IsServer()) {
failReg.SendEvent(RE::BSFixedString(error)); FFIServerError server_error = error.AsServer();
logger::error(FMT_STRING("StatusCheck server error: {} {} {}"), server_error.status, server_error.title, server_error.detail);
failReg.SendEvent(true, server_error.status, RE::BSFixedString(server_error.title), RE::BSFixedString(server_error.detail), RE::BSFixedString());
} else {
const char* network_error = error.AsNetwork();
logger::error(FMT_STRING("StatusCheck network error: {}"), network_error);
failReg.SendEvent(false, 0, RE::BSFixedString(), RE::BSFixedString(), RE::BSFixedString(network_error));
}
} }
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);

View File

@ -73,7 +73,7 @@ void CreateInteriorRefListImpl(RE::BSFixedString api_url, RE::BSFixedString api_
SKSE::RegistrationMap<int> successReg = SKSE::RegistrationMap<int>(); SKSE::RegistrationMap<int> successReg = SKSE::RegistrationMap<int>();
successReg.Register(quest, RE::BSFixedString("OnCreateInteriorRefListSuccess")); successReg.Register(quest, RE::BSFixedString("OnCreateInteriorRefListSuccess"));
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>(); SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg = SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString>();
failReg.Register(quest, RE::BSFixedString("OnCreateInteriorRefListFail")); failReg.Register(quest, RE::BSFixedString("OnCreateInteriorRefListFail"));
// TODO: may need to dynamically pass shop cell into this function // TODO: may need to dynamically pass shop cell into this function
@ -81,7 +81,7 @@ void CreateInteriorRefListImpl(RE::BSFixedString api_url, RE::BSFixedString api_
logger::info(FMT_STRING("CreateInteriorRefListImpl lookup cell override name: {} id: {:x}"), cell->GetName(), (uint32_t)cell->GetFormID()); logger::info(FMT_STRING("CreateInteriorRefListImpl lookup cell override name: {} id: {:x}"), cell->GetName(), (uint32_t)cell->GetFormID());
if (!cell) { if (!cell) {
logger::error("CreateInteriorRefListImpl cell is null!"); logger::error("CreateInteriorRefListImpl cell is null!");
failReg.SendEvent("Could not find Cell with the editor ID: BREmpty"); failReg.SendEvent(false, 0, "", "", "Could not find Cell with the editor ID: BREmpty");
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
return; return;
@ -198,9 +198,16 @@ void CreateInteriorRefListImpl(RE::BSFixedString api_url, RE::BSFixedString api_
logger::info(FMT_STRING("CreateInteriorRefList success: {}"), interior_ref_list_id); logger::info(FMT_STRING("CreateInteriorRefList success: {}"), interior_ref_list_id);
successReg.SendEvent(interior_ref_list_id); successReg.SendEvent(interior_ref_list_id);
} else { } else {
const char* error = result.AsErr(); FFIError error = result.AsErr();
logger::error(FMT_STRING("CreateInteriorRefList failure: {}"), error); if (error.IsServer()) {
failReg.SendEvent(RE::BSFixedString(error)); FFIServerError server_error = error.AsServer();
logger::error(FMT_STRING("CreateInteriorRefList server error: {} {} {}"), server_error.status, server_error.title, server_error.detail);
failReg.SendEvent(true, server_error.status, RE::BSFixedString(server_error.title), RE::BSFixedString(server_error.detail), RE::BSFixedString());
} else {
const char* network_error = error.AsNetwork();
logger::error(FMT_STRING("CreateInteriorRefList network error: {}"), network_error);
failReg.SendEvent(false, 0, RE::BSFixedString(), RE::BSFixedString(), RE::BSFixedString(network_error));
}
} }
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
@ -289,26 +296,26 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
SKSE::RegistrationMap<bool, std::vector<RE::TESObjectREFR*>> successReg = SKSE::RegistrationMap<bool, std::vector<RE::TESObjectREFR*>>(); SKSE::RegistrationMap<bool, std::vector<RE::TESObjectREFR*>> successReg = SKSE::RegistrationMap<bool, std::vector<RE::TESObjectREFR*>>();
successReg.Register(quest, RE::BSFixedString("OnLoadInteriorRefListSuccess")); successReg.Register(quest, RE::BSFixedString("OnLoadInteriorRefListSuccess"));
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>(); SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg = SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString>();
failReg.Register(quest, RE::BSFixedString("OnLoadInteriorRefListFail")); failReg.Register(quest, RE::BSFixedString("OnLoadInteriorRefListFail"));
if (!target_ref) { if (!target_ref) {
logger::error("LoadRefsTask target_ref is null!"); logger::error("LoadRefsTask target_ref is null!");
failReg.SendEvent("Spawn target reference is null"); failReg.SendEvent(false, 0, "", "", "Spawn target reference is null");
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
return; return;
} }
if (!private_chest) { if (!private_chest) {
logger::error("LoadRefsTask private_chest is null!"); logger::error("LoadRefsTask private_chest is null!");
failReg.SendEvent("Private merchant chest reference is null"); failReg.SendEvent(false, 0, "", "", "Private merchant chest reference is null");
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
return; return;
} }
if (!public_chest) { if (!public_chest) {
logger::error("LoadRefsTask public_chest is null!"); logger::error("LoadRefsTask public_chest is null!");
failReg.SendEvent("Public merchant chest reference is null"); failReg.SendEvent(false, 0, "", "", "Public merchant chest reference is null");
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
return; return;
@ -318,7 +325,7 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
logger::info(FMT_STRING("LoadRefsImpl lookup cell override name: {} id: {:x}"), cell->GetName(), (uint32_t)cell->GetFormID()); logger::info(FMT_STRING("LoadRefsImpl lookup cell override name: {} id: {:x}"), cell->GetName(), (uint32_t)cell->GetFormID());
if (!cell) { if (!cell) {
logger::error("LoadRefsTask cell is null!"); logger::error("LoadRefsTask cell is null!");
failReg.SendEvent("Lookup failed for the shop Cell: BREmpty"); failReg.SendEvent(false, 0, "", "", "Lookup failed for the shop Cell: BREmpty");
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
return; return;
@ -365,7 +372,7 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
game_ref = PlaceAtMe_Native(a_vm, 0, target_ref, form, 1, false, false); game_ref = PlaceAtMe_Native(a_vm, 0, target_ref, form, 1, false, false);
if (!game_ref) { if (!game_ref) {
logger::error("LoadInteriorRefList failed to place new ref in cell!"); logger::error("LoadInteriorRefList failed to place new ref in cell!");
failReg.SendEvent("Failed to place a new ref into the cell"); failReg.SendEvent(false, 0, "", "", "Failed to place a new ref into the cell");
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
return; return;
@ -390,7 +397,7 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
RE::TESForm* form = data_handler->LookupForm((*maybe_form_id).second, MOD_NAME); RE::TESForm* form = data_handler->LookupForm((*maybe_form_id).second, MOD_NAME);
if (!form) { if (!form) {
logger::error("LoadInteriorRefList failed to find shelf base form!"); logger::error("LoadInteriorRefList failed to find shelf base form!");
failReg.SendEvent("Failed to place a shelf into the cell, could not find shelf base form"); failReg.SendEvent(false, 0, "", "", "Failed to place a shelf into the cell, could not find shelf base form");
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
return; return;
@ -420,7 +427,7 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
RE::TESForm* button_form = data_handler->LookupForm(button.form_id, MOD_NAME); RE::TESForm* button_form = data_handler->LookupForm(button.form_id, MOD_NAME);
if (!button_form) { if (!button_form) {
logger::error("LoadInteriorRefList failed to find shelf button base form!"); logger::error("LoadInteriorRefList failed to find shelf button base form!");
failReg.SendEvent("Failed to place a shelf button into the cell, could not find shelf button base form"); failReg.SendEvent(false, 0, "", "", "Failed to place a shelf button into the cell, could not find shelf button base form");
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
return; return;
@ -451,7 +458,7 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
} }
} else { } else {
logger::error("LoadInteriorRefList unrecognized shelf type!"); logger::error("LoadInteriorRefList unrecognized shelf type!");
failReg.SendEvent(fmt::format(FMT_STRING("Failed to place a shelf into the cell, unrecognized shelf_type: {}"), shelf.shelf_type)); failReg.SendEvent(false, 0, "", "", fmt::format(FMT_STRING("Failed to place a shelf into the cell, unrecognized shelf_type: {}"), shelf.shelf_type));
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
return; return;
@ -460,9 +467,16 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
// TODO: load shop vendor(s) // TODO: load shop vendor(s)
} else { } else {
const char * error = result.AsErr(); FFIError error = result.AsErr();
logger::error(FMT_STRING("LoadInteriorRefList get_interior_ref_list error: {}"), error); if (error.IsServer()) {
failReg.SendEvent(RE::BSFixedString(error)); FFIServerError server_error = error.AsServer();
logger::error(FMT_STRING("LoadInteriorRefList server error: {} {} {}"), server_error.status, server_error.title, server_error.detail);
failReg.SendEvent(true, server_error.status, RE::BSFixedString(server_error.title), RE::BSFixedString(server_error.detail), RE::BSFixedString());
} else {
const char* network_error = error.AsNetwork();
logger::error(FMT_STRING("LoadInteriorRefList network error: {}"), network_error);
failReg.SendEvent(false, 0, RE::BSFixedString(), RE::BSFixedString(), RE::BSFixedString(network_error));
}
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
return; return;

View File

@ -237,7 +237,7 @@ void FillShelf(
RE::TESObjectREFR* merchant_chest, RE::TESObjectREFR* merchant_chest,
int page, int page,
SKSE::RegistrationMap<bool> successReg, SKSE::RegistrationMap<bool> successReg,
SKSE::RegistrationMap<RE::BSFixedString> failReg SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg
) { ) {
RE::TESDataHandler* data_handler = RE::TESDataHandler::GetSingleton(); RE::TESDataHandler* data_handler = RE::TESDataHandler::GetSingleton();
RE::BSScript::Internal::VirtualMachine * a_vm = RE::BSScript::Internal::VirtualMachine::GetSingleton(); RE::BSScript::Internal::VirtualMachine * a_vm = RE::BSScript::Internal::VirtualMachine::GetSingleton();
@ -426,7 +426,7 @@ void FillShelf(
RE::TESObjectREFR* next_ref = merchant_shelf->GetLinkedRef(next_keyword); RE::TESObjectREFR* next_ref = merchant_shelf->GetLinkedRef(next_keyword);
if (!next_ref) { if (!next_ref) {
logger::error("FillShelf next_ref is null!"); logger::error("FillShelf next_ref is null!");
failReg.SendEvent("Could not find the shelf's next button"); failReg.SendEvent(false, 0, "", "", "Could not find the shelf's next button");
successReg.Unregister(merchant_chest); successReg.Unregister(merchant_chest);
failReg.Unregister(merchant_chest); failReg.Unregister(merchant_chest);
return; return;
@ -434,7 +434,7 @@ void FillShelf(
RE::TESObjectREFR* prev_ref = merchant_shelf->GetLinkedRef(prev_keyword); RE::TESObjectREFR* prev_ref = merchant_shelf->GetLinkedRef(prev_keyword);
if (!prev_ref) { if (!prev_ref) {
logger::error("FillShelf prev_ref is null!"); logger::error("FillShelf prev_ref is null!");
failReg.SendEvent("Could not find the shelf's previous button"); failReg.SendEvent(false, 0, "", "", "Could not find the shelf's previous button");
successReg.Unregister(merchant_chest); successReg.Unregister(merchant_chest);
failReg.Unregister(merchant_chest); failReg.Unregister(merchant_chest);
return; return;
@ -474,12 +474,12 @@ void LoadShelfPageTask(
// Since this method is running asyncronously in a thread, set up a callback on the trigger ref that will receive an event with the result // Since this method is running asyncronously in a thread, set up a callback on the trigger ref that will receive an event with the result
SKSE::RegistrationMap<bool> successReg = SKSE::RegistrationMap<bool>(); SKSE::RegistrationMap<bool> successReg = SKSE::RegistrationMap<bool>();
successReg.Register(merchant_chest, RE::BSFixedString("OnLoadShelfPageSuccess")); successReg.Register(merchant_chest, RE::BSFixedString("OnLoadShelfPageSuccess"));
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>(); SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg = SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString>();
failReg.Register(merchant_chest, RE::BSFixedString("OnLoadShelfPageFail")); failReg.Register(merchant_chest, RE::BSFixedString("OnLoadShelfPageFail"));
if (!ClearMerchandise(merchant_shelf)) { if (!ClearMerchandise(merchant_shelf)) {
logger::error("LoadShelfPageTask ClearMerchandise returned a fail code"); logger::error("LoadShelfPageTask ClearMerchandise returned a fail code");
failReg.SendEvent(RE::BSFixedString("Failed to clear existing merchandise from shelf")); failReg.SendEvent(false, 0, "", "", RE::BSFixedString("Failed to clear existing merchandise from shelf"));
successReg.Unregister(merchant_chest); successReg.Unregister(merchant_chest);
failReg.Unregister(merchant_chest); failReg.Unregister(merchant_chest);
return; return;
@ -498,11 +498,11 @@ void FillShelves(
std::vector<RE::TESObjectREFR*> merchant_shelves, std::vector<RE::TESObjectREFR*> merchant_shelves,
RE::TESObjectREFR* merchant_chest, RE::TESObjectREFR* merchant_chest,
SKSE::RegistrationMap<bool> successReg, SKSE::RegistrationMap<bool> successReg,
SKSE::RegistrationMap<RE::BSFixedString> failReg SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg
) { ) {
if (!ClearAllMerchandise(cell)) { if (!ClearAllMerchandise(cell)) {
logger::error("FillShelves ClearAllMerchandise returned a fail code"); logger::error("FillShelves ClearAllMerchandise returned a fail code");
failReg.SendEvent(RE::BSFixedString("Failed to clear existing merchandise from shelves")); failReg.SendEvent(false, 0, "", "", RE::BSFixedString("Failed to clear existing merchandise from shelves"));
successReg.Unregister(merchant_chest); successReg.Unregister(merchant_chest);
failReg.Unregister(merchant_chest); failReg.Unregister(merchant_chest);
return; return;
@ -533,7 +533,7 @@ void LoadMerchTask(
// Since this method is running asyncronously in a thread, set up a callback on the trigger ref that will receive an event with the result // Since this method is running asyncronously in a thread, set up a callback on the trigger ref that will receive an event with the result
SKSE::RegistrationMap<bool> successReg = SKSE::RegistrationMap<bool>(); SKSE::RegistrationMap<bool> successReg = SKSE::RegistrationMap<bool>();
successReg.Register(merchant_chest, RE::BSFixedString("OnLoadMerchandiseSuccess")); successReg.Register(merchant_chest, RE::BSFixedString("OnLoadMerchandiseSuccess"));
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>(); SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg = SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString>();
failReg.Register(merchant_chest, RE::BSFixedString("OnLoadMerchandiseFail")); failReg.Register(merchant_chest, RE::BSFixedString("OnLoadMerchandiseFail"));
if (result.IsOk()) { if (result.IsOk()) {
@ -563,9 +563,16 @@ void LoadMerchTask(
FillShelves(cell, merchant_shelves, merchant_chest, successReg, failReg); FillShelves(cell, merchant_shelves, merchant_chest, successReg, failReg);
} else { } else {
const char* error = result.AsErr(); FFIError error = result.AsErr();
logger::error(FMT_STRING("LoadMerchTask get_merchandise_list error: {}"), error); if (error.IsServer()) {
failReg.SendEvent(RE::BSFixedString(error)); FFIServerError server_error = error.AsServer();
logger::error(FMT_STRING("LoadMerchTask server error: {} {} {}"), server_error.status, server_error.title, server_error.detail);
failReg.SendEvent(true, server_error.status, RE::BSFixedString(server_error.title), RE::BSFixedString(server_error.detail), RE::BSFixedString());
} else {
const char* network_error = error.AsNetwork();
logger::error(FMT_STRING("LoadMerchTask network error: {}"), network_error);
failReg.SendEvent(false, 0, RE::BSFixedString(), RE::BSFixedString(), RE::BSFixedString(network_error));
}
successReg.Unregister(merchant_chest); successReg.Unregister(merchant_chest);
failReg.Unregister(merchant_chest); failReg.Unregister(merchant_chest);
return; return;
@ -990,7 +997,7 @@ void CreateMerchandiseListImpl(
SKSE::RegistrationMap<bool> successReg = SKSE::RegistrationMap<bool>(); SKSE::RegistrationMap<bool> successReg = SKSE::RegistrationMap<bool>();
successReg.Register(merchant_chest, RE::BSFixedString("OnCreateMerchandiseSuccess")); successReg.Register(merchant_chest, RE::BSFixedString("OnCreateMerchandiseSuccess"));
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>(); SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg = SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString>();
failReg.Register(merchant_chest, RE::BSFixedString("OnCreateMerchandiseFail")); failReg.Register(merchant_chest, RE::BSFixedString("OnCreateMerchandiseFail"));
RE::InventoryChanges* inventory_changes = merchant_chest->GetInventoryChanges(); RE::InventoryChanges* inventory_changes = merchant_chest->GetInventoryChanges();
@ -1073,9 +1080,16 @@ void CreateMerchandiseListImpl(
logger::info("CreateMerchandiseList success"); logger::info("CreateMerchandiseList success");
successReg.SendEvent(true); successReg.SendEvent(true);
} else { } else {
const char* error = result.AsErr(); FFIError error = result.AsErr();
logger::error(FMT_STRING("CreateMerchandiseList failure: {}"), error); if (error.IsServer()) {
failReg.SendEvent(RE::BSFixedString(error)); FFIServerError server_error = error.AsServer();
logger::error(FMT_STRING("CreateMerchandiseList server error: {} {} {}"), server_error.status, server_error.title, server_error.detail);
failReg.SendEvent(true, server_error.status, RE::BSFixedString(server_error.title), RE::BSFixedString(server_error.detail), RE::BSFixedString());
} else {
const char* network_error = error.AsNetwork();
logger::error(FMT_STRING("CreateMerchandiseList network error: {}"), network_error);
failReg.SendEvent(false, 0, RE::BSFixedString(), RE::BSFixedString(), RE::BSFixedString(network_error));
}
} }
successReg.Unregister(merchant_chest); successReg.Unregister(merchant_chest);
failReg.Unregister(merchant_chest); failReg.Unregister(merchant_chest);

View File

@ -9,7 +9,7 @@ void CreateOwnerImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, RE::B
SKSE::RegistrationMap<int> successReg = SKSE::RegistrationMap<int>(); SKSE::RegistrationMap<int> successReg = SKSE::RegistrationMap<int>();
successReg.Register(quest, RE::BSFixedString("OnCreateOwnerSuccess")); successReg.Register(quest, RE::BSFixedString("OnCreateOwnerSuccess"));
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>(); SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg = SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString>();
failReg.Register(quest, RE::BSFixedString("OnCreateOwnerFail")); failReg.Register(quest, RE::BSFixedString("OnCreateOwnerFail"));
logger::info(FMT_STRING("CreateOwner api_url: {}, api_key: {}, name: {}, mod_version: {}"), api_url, api_key, name, mod_version); logger::info(FMT_STRING("CreateOwner api_url: {}, api_key: {}, name: {}, mod_version: {}"), api_url, api_key, name, mod_version);
@ -19,9 +19,16 @@ void CreateOwnerImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, RE::B
logger::info(FMT_STRING("CreateOwner success: {}"), owner.id); logger::info(FMT_STRING("CreateOwner success: {}"), owner.id);
successReg.SendEvent(owner.id); successReg.SendEvent(owner.id);
} else { } else {
RE::BSFixedString error = result.AsErr(); FFIError error = result.AsErr();
logger::info(FMT_STRING("CreateOwner failure: {}"), error); if (error.IsServer()) {
failReg.SendEvent(error); FFIServerError server_error = error.AsServer();
logger::error(FMT_STRING("CreateOwner server error: {} {} {}"), server_error.status, server_error.title, server_error.detail);
failReg.SendEvent(true, server_error.status, RE::BSFixedString(server_error.title), RE::BSFixedString(server_error.detail), RE::BSFixedString());
} else {
const char* network_error = error.AsNetwork();
logger::error(FMT_STRING("CreateOwner network error: {}"), network_error);
failReg.SendEvent(false, 0, RE::BSFixedString(), RE::BSFixedString(), RE::BSFixedString(network_error));
}
} }
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
@ -48,7 +55,7 @@ void UpdateOwnerImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, int32
SKSE::RegistrationMap<int> successReg = SKSE::RegistrationMap<int>(); SKSE::RegistrationMap<int> successReg = SKSE::RegistrationMap<int>();
successReg.Register(quest, RE::BSFixedString("OnUpdateOwnerSuccess")); successReg.Register(quest, RE::BSFixedString("OnUpdateOwnerSuccess"));
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>(); SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg = SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString>();
failReg.Register(quest, RE::BSFixedString("OnUpdateOwnerFail")); failReg.Register(quest, RE::BSFixedString("OnUpdateOwnerFail"));
logger::info(FMT_STRING("UpdateOwner api_url: {}, api_key: {}, name: {}, mod_version: {}"), api_url, api_key, name, mod_version); logger::info(FMT_STRING("UpdateOwner api_url: {}, api_key: {}, name: {}, mod_version: {}"), api_url, api_key, name, mod_version);
@ -58,9 +65,16 @@ void UpdateOwnerImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, int32
logger::info(FMT_STRING("UpdateOwner success: {}"), owner.id); logger::info(FMT_STRING("UpdateOwner success: {}"), owner.id);
successReg.SendEvent(owner.id); successReg.SendEvent(owner.id);
} else { } else {
RE::BSFixedString error = result.AsErr(); FFIError error = result.AsErr();
logger::info(FMT_STRING("UpdateOwner failure: {}"), error); if (error.IsServer()) {
failReg.SendEvent(error); FFIServerError server_error = error.AsServer();
logger::error(FMT_STRING("UpdateOwner server error: {} {} {}"), server_error.status, server_error.title, server_error.detail);
failReg.SendEvent(true, server_error.status, RE::BSFixedString(server_error.title), RE::BSFixedString(server_error.detail), RE::BSFixedString());
} else {
const char* network_error = error.AsNetwork();
logger::error(FMT_STRING("UpdateOwner network error: {}"), network_error);
failReg.SendEvent(false, 0, RE::BSFixedString(), RE::BSFixedString(), RE::BSFixedString(network_error));
}
} }
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);

View File

@ -11,7 +11,7 @@ void CreateShopImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, RE::BS
SKSE::RegistrationMap<int, RE::BSFixedString, RE::BSFixedString, int, RE::BSFixedString, std::vector<RE::BGSKeyword*>, bool> successReg = SKSE::RegistrationMap<int, RE::BSFixedString, RE::BSFixedString, int, RE::BSFixedString, std::vector<RE::BGSKeyword*>, bool> successReg =
SKSE::RegistrationMap<int, RE::BSFixedString, RE::BSFixedString, int, RE::BSFixedString, std::vector<RE::BGSKeyword*>, bool>(); SKSE::RegistrationMap<int, RE::BSFixedString, RE::BSFixedString, int, RE::BSFixedString, std::vector<RE::BGSKeyword*>, bool>();
successReg.Register(quest, RE::BSFixedString("OnCreateShopSuccess")); successReg.Register(quest, RE::BSFixedString("OnCreateShopSuccess"));
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>(); SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg = SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString>();
failReg.Register(quest, RE::BSFixedString("OnCreateShopFail")); failReg.Register(quest, RE::BSFixedString("OnCreateShopFail"));
logger::info(FMT_STRING("CreateShop api_url: {}, api_key: {}, name: {}, description: {}"), api_url, api_key, name, description); logger::info(FMT_STRING("CreateShop api_url: {}, api_key: {}, name: {}, description: {}"), api_url, api_key, name, description);
@ -38,9 +38,16 @@ void CreateShopImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, RE::BS
} }
successReg.SendEvent(shop.id, RE::BSFixedString(shop.name), RE::BSFixedString(shop.description), shop.gold, RE::BSFixedString(shop.shop_type), keyword_forms, shop.vendor_keywords_exclude); successReg.SendEvent(shop.id, RE::BSFixedString(shop.name), RE::BSFixedString(shop.description), shop.gold, RE::BSFixedString(shop.shop_type), keyword_forms, shop.vendor_keywords_exclude);
} else { } else {
const char* error = result.AsErr(); FFIError error = result.AsErr();
logger::error(FMT_STRING("CreateShop failure: {}"), error); if (error.IsServer()) {
failReg.SendEvent(RE::BSFixedString(error)); FFIServerError server_error = error.AsServer();
logger::error(FMT_STRING("CreateShop server error: {} {} {}"), server_error.status, server_error.title, server_error.detail);
failReg.SendEvent(true, server_error.status, RE::BSFixedString(server_error.title), RE::BSFixedString(server_error.detail), RE::BSFixedString());
} else {
const char* network_error = error.AsNetwork();
logger::error(FMT_STRING("CreateShop network error: {}"), network_error);
failReg.SendEvent(false, 0, RE::BSFixedString(), RE::BSFixedString(), RE::BSFixedString(network_error));
}
} }
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
@ -79,7 +86,7 @@ void UpdateShopImpl(
SKSE::RegistrationMap<int, RE::BSFixedString, RE::BSFixedString, int, RE::BSFixedString, std::vector<RE::BGSKeyword*>, bool> successReg = SKSE::RegistrationMap<int, RE::BSFixedString, RE::BSFixedString, int, RE::BSFixedString, std::vector<RE::BGSKeyword*>, bool> successReg =
SKSE::RegistrationMap<int, RE::BSFixedString, RE::BSFixedString, int, RE::BSFixedString, std::vector<RE::BGSKeyword*>, bool>(); SKSE::RegistrationMap<int, RE::BSFixedString, RE::BSFixedString, int, RE::BSFixedString, std::vector<RE::BGSKeyword*>, bool>();
successReg.Register(quest, RE::BSFixedString("OnUpdateShopSuccess")); successReg.Register(quest, RE::BSFixedString("OnUpdateShopSuccess"));
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>(); SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg = SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString>();
failReg.Register(quest, RE::BSFixedString("OnUpdateShopFail")); failReg.Register(quest, RE::BSFixedString("OnUpdateShopFail"));
std::vector<const char*> keyword_strings; std::vector<const char*> keyword_strings;
@ -111,9 +118,16 @@ void UpdateShopImpl(
} }
successReg.SendEvent(shop.id, RE::BSFixedString(shop.name), RE::BSFixedString(shop.description), shop.gold, RE::BSFixedString(shop.shop_type), keyword_forms, shop.vendor_keywords_exclude); successReg.SendEvent(shop.id, RE::BSFixedString(shop.name), RE::BSFixedString(shop.description), shop.gold, RE::BSFixedString(shop.shop_type), keyword_forms, shop.vendor_keywords_exclude);
} else { } else {
const char* error = result.AsErr(); FFIError error = result.AsErr();
logger::error(FMT_STRING("UpdateShop failure: {}"), error); if (error.IsServer()) {
failReg.SendEvent(RE::BSFixedString(error)); FFIServerError server_error = error.AsServer();
logger::error(FMT_STRING("UpdateShop server error: {} {} {}"), server_error.status, server_error.title, server_error.detail);
failReg.SendEvent(true, server_error.status, RE::BSFixedString(server_error.title), RE::BSFixedString(server_error.detail), RE::BSFixedString());
} else {
const char* network_error = error.AsNetwork();
logger::error(FMT_STRING("UpdateShop network error: {}"), network_error);
failReg.SendEvent(false, 0, RE::BSFixedString(), RE::BSFixedString(), RE::BSFixedString(network_error));
}
} }
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
@ -153,7 +167,7 @@ void GetShopImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, int32_t i
SKSE::RegistrationMap<int, RE::BSFixedString, RE::BSFixedString, int, RE::BSFixedString, std::vector<RE::BGSKeyword*>, bool> successReg = SKSE::RegistrationMap<int, RE::BSFixedString, RE::BSFixedString, int, RE::BSFixedString, std::vector<RE::BGSKeyword*>, bool> successReg =
SKSE::RegistrationMap<int, RE::BSFixedString, RE::BSFixedString, int, RE::BSFixedString, std::vector<RE::BGSKeyword*>, bool>(); SKSE::RegistrationMap<int, RE::BSFixedString, RE::BSFixedString, int, RE::BSFixedString, std::vector<RE::BGSKeyword*>, bool>();
successReg.Register(quest, RE::BSFixedString("OnGetShopSuccess")); successReg.Register(quest, RE::BSFixedString("OnGetShopSuccess"));
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>(); SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg = SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString>();
failReg.Register(quest, RE::BSFixedString("OnGetShopFail")); failReg.Register(quest, RE::BSFixedString("OnGetShopFail"));
logger::info(FMT_STRING("GetShop api_url: {}, api_key: {}, id: {}"), api_url, api_key, id); logger::info(FMT_STRING("GetShop api_url: {}, api_key: {}, id: {}"), api_url, api_key, id);
@ -180,9 +194,16 @@ void GetShopImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, int32_t i
} }
successReg.SendEvent(shop.id, RE::BSFixedString(shop.name), RE::BSFixedString(shop.description), shop.gold, RE::BSFixedString(shop.shop_type), keyword_forms, shop.vendor_keywords_exclude); successReg.SendEvent(shop.id, RE::BSFixedString(shop.name), RE::BSFixedString(shop.description), shop.gold, RE::BSFixedString(shop.shop_type), keyword_forms, shop.vendor_keywords_exclude);
} else { } else {
const char* error = result.AsErr(); FFIError error = result.AsErr();
logger::error(FMT_STRING("GetShop failure: {}"), error); if (error.IsServer()) {
failReg.SendEvent(RE::BSFixedString(error)); FFIServerError server_error = error.AsServer();
logger::error(FMT_STRING("GetShop server error: {} {} {}"), server_error.status, server_error.title, server_error.detail);
failReg.SendEvent(true, server_error.status, RE::BSFixedString(server_error.title), RE::BSFixedString(server_error.detail), RE::BSFixedString());
} else {
const char* network_error = error.AsNetwork();
logger::error(FMT_STRING("GetShop network error: {}"), network_error);
failReg.SendEvent(false, 0, RE::BSFixedString(), RE::BSFixedString(), RE::BSFixedString(network_error));
}
} }
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
@ -211,7 +232,7 @@ void ListShopsImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, RE::TES
SKSE::RegistrationMap<std::vector<int>, std::vector<RE::BSFixedString>, std::vector<RE::BSFixedString>, std::vector<int>, std::vector<RE::BSFixedString>, std::vector<RE::BGSKeyword*>, std::vector<bool>> successReg = SKSE::RegistrationMap<std::vector<int>, std::vector<RE::BSFixedString>, std::vector<RE::BSFixedString>, std::vector<int>, std::vector<RE::BSFixedString>, std::vector<RE::BGSKeyword*>, std::vector<bool>> successReg =
SKSE::RegistrationMap<std::vector<int>, std::vector<RE::BSFixedString>, std::vector<RE::BSFixedString>, std::vector<int>, std::vector<RE::BSFixedString>, std::vector<RE::BGSKeyword*>, std::vector<bool>>(); SKSE::RegistrationMap<std::vector<int>, std::vector<RE::BSFixedString>, std::vector<RE::BSFixedString>, std::vector<int>, std::vector<RE::BSFixedString>, std::vector<RE::BGSKeyword*>, std::vector<bool>>();
successReg.Register(quest, RE::BSFixedString("OnListShopsSuccess")); successReg.Register(quest, RE::BSFixedString("OnListShopsSuccess"));
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>(); SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg = SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString>();
failReg.Register(quest, RE::BSFixedString("OnListShopsFail")); failReg.Register(quest, RE::BSFixedString("OnListShopsFail"));
logger::info(FMT_STRING("ListShops api_url: {}, api_key: {}"), api_url, api_key); logger::info(FMT_STRING("ListShops api_url: {}, api_key: {}"), api_url, api_key);
@ -259,9 +280,16 @@ void ListShopsImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, RE::TES
} }
successReg.SendEvent(id_vec, name_vec, description_vec, gold_vec, shop_type_vec, keywords_vec, keywords_exclude_vec); successReg.SendEvent(id_vec, name_vec, description_vec, gold_vec, shop_type_vec, keywords_vec, keywords_exclude_vec);
} else { } else {
const char* error = result.AsErr(); FFIError error = result.AsErr();
logger::error(FMT_STRING("ListShops failure: {}"), error); if (error.IsServer()) {
failReg.SendEvent(RE::BSFixedString(error)); FFIServerError server_error = error.AsServer();
logger::error(FMT_STRING("ListShops server error: {} {} {}"), server_error.status, server_error.title, server_error.detail);
failReg.SendEvent(true, server_error.status, RE::BSFixedString(server_error.title), RE::BSFixedString(server_error.detail), RE::BSFixedString());
} else {
const char* network_error = error.AsNetwork();
logger::error(FMT_STRING("ListShops network error: {}"), network_error);
failReg.SendEvent(false, 0, RE::BSFixedString(), RE::BSFixedString(), RE::BSFixedString(network_error));
}
} }
successReg.Unregister(quest); successReg.Unregister(quest);
failReg.Unregister(quest); failReg.Unregister(quest);
@ -331,13 +359,13 @@ void RefreshShopGoldImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, i
SKSE::RegistrationMap<int> successReg = SKSE::RegistrationMap<int>(); SKSE::RegistrationMap<int> successReg = SKSE::RegistrationMap<int>();
successReg.Register(merchant_chest, RE::BSFixedString("OnRefreshShopGoldSuccess")); successReg.Register(merchant_chest, RE::BSFixedString("OnRefreshShopGoldSuccess"));
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>(); SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg = SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString>();
failReg.Register(merchant_chest, RE::BSFixedString("OnRefreshShopGoldFail")); failReg.Register(merchant_chest, RE::BSFixedString("OnRefreshShopGoldFail"));
RE::TESForm* gold_form = RE::TESForm::LookupByID(15); RE::TESForm* gold_form = RE::TESForm::LookupByID(15);
if (!gold_form) { if (!gold_form) {
logger::error("RefreshShopGoldImpl failed to lookup gold form"); logger::error("RefreshShopGoldImpl failed to lookup gold form");
failReg.SendEvent(RE::BSFixedString("Failed to lookup gold form")); failReg.SendEvent(false, 0, "", "", RE::BSFixedString("Failed to lookup gold form"));
successReg.Unregister(merchant_chest); successReg.Unregister(merchant_chest);
failReg.Unregister(merchant_chest); failReg.Unregister(merchant_chest);
return; return;
@ -345,7 +373,7 @@ void RefreshShopGoldImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, i
RE::TESBoundObject* gold = static_cast<RE::TESBoundObject*>(gold_form); RE::TESBoundObject* gold = static_cast<RE::TESBoundObject*>(gold_form);
if (!gold) { if (!gold) {
logger::error("RefreshShopGoldImpl failed to cast gold form to gold bound object"); logger::error("RefreshShopGoldImpl failed to cast gold form to gold bound object");
failReg.SendEvent(RE::BSFixedString("Failed to cast gold form to gold bound object")); failReg.SendEvent(false, 0, "", "", RE::BSFixedString("Failed to cast gold form to gold bound object"));
successReg.Unregister(merchant_chest); successReg.Unregister(merchant_chest);
failReg.Unregister(merchant_chest); failReg.Unregister(merchant_chest);
return; return;
@ -361,9 +389,16 @@ void RefreshShopGoldImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, i
} }
successReg.SendEvent(shop.gold); successReg.SendEvent(shop.gold);
} else { } else {
const char* error = result.AsErr(); FFIError error = result.AsErr();
logger::error(FMT_STRING("RefreshShopGold failure: {}"), error); if (error.IsServer()) {
failReg.SendEvent(RE::BSFixedString(error)); FFIServerError server_error = error.AsServer();
logger::error(FMT_STRING("RefreshShopGold server error: {} {} {}"), server_error.status, server_error.title, server_error.detail);
failReg.SendEvent(true, server_error.status, RE::BSFixedString(server_error.title), RE::BSFixedString(server_error.detail), RE::BSFixedString());
} else {
const char* network_error = error.AsNetwork();
logger::error(FMT_STRING("RefreshShopGold network error: {}"), network_error);
failReg.SendEvent(false, 0, RE::BSFixedString(), RE::BSFixedString(), RE::BSFixedString(network_error));
}
} }
successReg.Unregister(merchant_chest); successReg.Unregister(merchant_chest);
failReg.Unregister(merchant_chest); failReg.Unregister(merchant_chest);

View File

@ -27,7 +27,7 @@ void CreateTransactionImpl(
SKSE::RegistrationMap<int, int, int> successReg = SKSE::RegistrationMap<int, int, int>(); SKSE::RegistrationMap<int, int, int> successReg = SKSE::RegistrationMap<int, int, int>();
successReg.Register(result_handler, RE::BSFixedString("OnCreateTransactionSuccess")); successReg.Register(result_handler, RE::BSFixedString("OnCreateTransactionSuccess"));
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>(); SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString> failReg = SKSE::RegistrationMap<bool, int, RE::BSFixedString, RE::BSFixedString, RE::BSFixedString>();
failReg.Register(result_handler, RE::BSFixedString("OnCreateTransactionFail")); failReg.Register(result_handler, RE::BSFixedString("OnCreateTransactionFail"));
const char * name = merch_base->GetName(); const char * name = merch_base->GetName();
@ -56,9 +56,16 @@ void CreateTransactionImpl(
logger::info(FMT_STRING("CreateTransaction success: {}"), saved_transaction.id); logger::info(FMT_STRING("CreateTransaction success: {}"), saved_transaction.id);
successReg.SendEvent(saved_transaction.id, saved_transaction.quantity, saved_transaction.amount); successReg.SendEvent(saved_transaction.id, saved_transaction.quantity, saved_transaction.amount);
} else { } else {
const char* error = result.AsErr(); FFIError error = result.AsErr();
logger::error(FMT_STRING("CreateTransaction failure: {}"), error); if (error.IsServer()) {
failReg.SendEvent(RE::BSFixedString(error)); FFIServerError server_error = error.AsServer();
logger::error(FMT_STRING("CreateTransaction server error: {} {} {}"), server_error.status, server_error.title, server_error.detail);
failReg.SendEvent(true, server_error.status, RE::BSFixedString(server_error.title), RE::BSFixedString(server_error.detail), RE::BSFixedString());
} else {
const char* network_error = error.AsNetwork();
logger::error(FMT_STRING("CreateTransaction network error: {}"), network_error);
failReg.SendEvent(false, 0, RE::BSFixedString(), RE::BSFixedString(), RE::BSFixedString(network_error));
}
} }
successReg.Unregister(result_handler); successReg.Unregister(result_handler);
failReg.Unregister(result_handler); failReg.Unregister(result_handler);