mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-28 21:35:42 +00:00
Include AI failure context in stream errors (#8193)
* Include AI failure context in stream errors * Fix AI diagnostics end condition logging
This commit is contained in:
@@ -58,6 +58,45 @@ namespace {
|
||||
return out.str();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto DescribeCurrentStateForLog(const ShardokEngine &engine) -> std::string {
|
||||
const auto *state = engine.GetCurrentGameState().Get();
|
||||
if (state == nullptr) { return "state=<null>"; }
|
||||
|
||||
const auto vectorSize = [](const auto *vector) -> size_t {
|
||||
return vector == nullptr ? 0 : vector->size();
|
||||
};
|
||||
|
||||
std::ostringstream out;
|
||||
out << "state={round=" << static_cast<int>(state->current_round())
|
||||
<< " current_player=" << static_cast<int>(state->current_player())
|
||||
<< " history_count=" << engine.GetUnfilteredHistoryCount();
|
||||
|
||||
if (const auto *status = state->status(); status != nullptr) {
|
||||
out << " status=" << static_cast<int>(status->state()) << " end_condition=";
|
||||
if (const auto *endCondition = status->end_game_condition(); endCondition != nullptr) {
|
||||
out << "{type=" << static_cast<int>(endCondition->victory_type())
|
||||
<< " victory_details=" << static_cast<int>(endCondition->victory_details())
|
||||
<< " draw_details=" << static_cast<int>(endCondition->draw_details()) << '}';
|
||||
} else {
|
||||
out << "<null>";
|
||||
}
|
||||
} else {
|
||||
out << " status=<null>";
|
||||
}
|
||||
|
||||
out << " units=" << vectorSize(state->units())
|
||||
<< " player_infos=" << vectorSize(state->player_infos());
|
||||
|
||||
if (const auto *hexMap = state->hex_map(); hexMap != nullptr) {
|
||||
out << " map=" << hexMap->row_count() << 'x' << hexMap->column_count();
|
||||
} else {
|
||||
out << " map=<null>";
|
||||
}
|
||||
|
||||
out << '}';
|
||||
return out.str();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class InvalidTokenException : public std::exception {};
|
||||
@@ -242,27 +281,32 @@ void ShardokGameController::DoAIThread() {
|
||||
aiThreadKeepGoing = !engine->GameIsOver();
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
std::ostringstream error;
|
||||
error << "AI error in game " << cachedGameId << ", player " << playerId << ", round "
|
||||
<< gsv.current_round() << ": " << e.what();
|
||||
|
||||
std::ostringstream context;
|
||||
context << "AI failure context: phase=" << aiPhase
|
||||
<< ", expected_history_count=" << expectedHistoryCount
|
||||
<< ", current_history_count=" << engine->GetUnfilteredHistoryCount()
|
||||
<< ", chosen_index=" << chosenIndex
|
||||
<< ", current_player=" << static_cast<int>(engine->GetCurrentPlayerId()) << ", "
|
||||
<< DescribeCurrentStateForLog(*engine);
|
||||
|
||||
const std::string commandsContext = availableCommands
|
||||
? DescribeCommandsForLog(*availableCommands)
|
||||
: "available_command_count=<cleared>";
|
||||
|
||||
std::cerr << "AI thread exception in game " << cachedGameId << ", player " << playerId
|
||||
<< ", round " << gsv.current_round() << ": " << e.what() << '\n';
|
||||
std::cerr << "AI failure context: phase=" << aiPhase
|
||||
<< ", expected_history_count=" << expectedHistoryCount
|
||||
<< ", current_history_count=" << engine->GetUnfilteredHistoryCount()
|
||||
<< ", chosen_index=" << chosenIndex
|
||||
<< ", current_player=" << static_cast<int>(engine->GetCurrentPlayerId())
|
||||
<< '\n';
|
||||
if (availableCommands) {
|
||||
std::cerr << DescribeCommandsForLog(*availableCommands) << '\n';
|
||||
} else {
|
||||
std::cerr << "available_command_count=<cleared>" << '\n';
|
||||
}
|
||||
std::cerr << context.str() << '\n';
|
||||
std::cerr << commandsContext << '\n';
|
||||
|
||||
void *backtraceArray[20];
|
||||
const int backtraceSize = backtrace(backtraceArray, 20);
|
||||
backtrace_symbols_fd(backtraceArray, backtraceSize, STDERR_FILENO);
|
||||
|
||||
aiThreadErrorMessage = "AI error in game " + cachedGameId + ", player " +
|
||||
std::to_string(playerId) + ", round " +
|
||||
std::to_string(gsv.current_round()) + ": " + e.what();
|
||||
aiThreadErrorMessage = error.str() + "\n" + context.str() + "\n" + commandsContext;
|
||||
aiThreadFailed.store(true);
|
||||
updateCondition.notify_all();
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user