From c5ac9bd6f0ef0b1ac8e626ffc5ab5f722d3b4aa0 Mon Sep 17 00:00:00 2001 From: gastank <42421688+gastank@users.noreply.github.com> Date: Wed, 5 Mar 2025 21:13:38 -0800 Subject: [PATCH] [Sim] add error levels to error() messages General descriptions: 0: Trivial 1: Moderate 2: Severe Specific errors: 10: Unsupported fight style 11: Invalid talent hash 12: Uses a work-in-progress spell --- engine/player/player.cpp | 5 +++-- engine/report/json/report_json.cpp | 8 +++++++- engine/report/report_html_sim.cpp | 2 +- engine/sc_enums.hpp | 11 +++++++++++ engine/sim/sim.cpp | 10 +++++----- engine/sim/sim.hpp | 27 +++++++++++++++++++++++---- engine/util/util.cpp | 15 +++++++++++++++ engine/util/util.hpp | 1 + qt/MainWindow.cpp | 6 +++--- qt/sc_SimulationThread.cpp | 8 ++++---- 10 files changed, 73 insertions(+), 20 deletions(-) diff --git a/engine/player/player.cpp b/engine/player/player.cpp index cf2e604c38c..69f28917460 100644 --- a/engine/player/player.cpp +++ b/engine/player/player.cpp @@ -1379,7 +1379,7 @@ void player_t::init() // Validate current fight style is supported by the actor's module. if ( !validate_fight_style( sim->fight_style ) ) { - sim->error( "{} does not support fight style {}, results may be unreliable.", *this, + sim->error( error_level_e::FIGHT_STYLE, "{} does not support fight style {}, results may be unreliable.", *this, util::fight_style_string( sim->fight_style ) ); } @@ -2711,7 +2711,8 @@ static std::string generate_traits_hash( player_t* player ) static void parse_traits_hash( const std::string& talents_str, player_t* player ) { auto do_error = [ player, &talents_str ]( std::string_view msg = {} ) { - player->sim->error( "Player {} has invalid talent tree hash {}{}{}", player->name(), talents_str, msg.empty() ? "" : ": ", msg ); + player->sim->error( error_level_e::TALENT_HASH, "Player {} has invalid talent tree hash {}{}{}", player->name(), + talents_str, msg.empty() ? "" : ": ", msg ); }; if ( talents_str.find_first_not_of( base64_char ) != std::string::npos ) diff --git a/engine/report/json/report_json.cpp b/engine/report/json/report_json.cpp index 9b599c2db15..439666557f8 100644 --- a/engine/report/json/report_json.cpp +++ b/engine/report/json/report_json.cpp @@ -1418,7 +1418,13 @@ void print_json_pretty( FILE* o, const sim_t& sim, const ::report::json::report_ if ( !sim.error_list.empty() ) { - root[ "notifications" ] = sim.error_list; + auto node = root[ "notifications" ]; + node.make_array(); + range::for_each( sim.error_list, [ & ]( const auto& error ) { + auto entry = node.add(); + entry[ "level" ] = error.first; + entry[ "message" ] = error.second; + } ); } std::array buffer; diff --git a/engine/report/report_html_sim.cpp b/engine/report/report_html_sim.cpp index c0326f9d43c..62640aef16e 100644 --- a/engine/report/report_html_sim.cpp +++ b/engine/report/report_html_sim.cpp @@ -1044,7 +1044,7 @@ void print_html_errors( report::sc_html_stream& os, const sim_t& sim ) os << "
\n";
 
     for ( const auto& error : sim.error_list )
-      os << util::encode_html( error ) << "\n";
+      os.format( "{}: {}\n", util::error_level_string( error.first ), error.second );
 
     os << "
\n\n"; } diff --git a/engine/sc_enums.hpp b/engine/sc_enums.hpp index d798b73e6b4..d799542e2c1 100644 --- a/engine/sc_enums.hpp +++ b/engine/sc_enums.hpp @@ -1475,3 +1475,14 @@ enum trait_definition_op : int TRAIT_OP_SET, TRAIT_OP_MUL }; + +// sim_t::error() severity level +enum error_level_e : unsigned short +{ + TRIVIAL = 0, + MODERATE, + SEVERE, + FIGHT_STYLE = 10, + TALENT_HASH, + WORK_IN_PROGRESS +}; \ No newline at end of file diff --git a/engine/sim/sim.cpp b/engine/sim/sim.cpp index c85b2d6811c..6d9d51cbe85 100644 --- a/engine/sim/sim.cpp +++ b/engine/sim/sim.cpp @@ -3143,13 +3143,13 @@ void sim_t::do_pause() } } -void sim_t::set_error(std::string error) +void sim_t::set_error( error_level_e level, std::string error ) { - util::replace_all( error, "\n", "" ); - fmt::print( stderr, "{}\n", error ); - std::fflush( stderr ); + util::replace_all( error, "\n", "" ); + fmt::print( stderr, "{}\n", error ); + std::fflush( stderr ); - error_list.push_back( std::move( error ) ); + error_list.emplace_back( level, std::move( error ) ); } /// merge sims diff --git a/engine/sim/sim.hpp b/engine/sim/sim.hpp index 9bcd5fbc618..0e8770afb07 100644 --- a/engine/sim/sim.hpp +++ b/engine/sim/sim.hpp @@ -589,7 +589,7 @@ struct sim_t : private sc_thread_t std::vector json_reports; std::string output_file_str, html_file_str, json_file_str; std::string reforge_plot_output_file_str; - std::vector error_list; + std::vector> error_list; int display_build; // 0: none, 1: normal (default), 2: version + hotfix only int report_precision; int report_pets_separately; @@ -730,25 +730,44 @@ struct sim_t : private sc_thread_t /** * Create error with printf formatting. */ + template + void errorf( error_level_e level, util::string_view format, Args&&... args ) + { + if ( thread_index != 0 ) + return; + + set_error( level, fmt::sprintf( format, std::forward(args)... ) ); + } + template void errorf( util::string_view format, Args&&... args ) { if ( thread_index != 0 ) return; - set_error( fmt::sprintf( format, std::forward(args)... ) ); + set_error( error_level_e::TRIVIAL, fmt::sprintf( format, std::forward(args)... ) ); } + /** * Create error using fmt libraries python-like formatting syntax. */ + template + void error( error_level_e level, fmt::format_string format, Args&&... args ) + { + if ( thread_index != 0 ) + return; + + set_error( level, fmt::vformat( format, fmt::make_format_args( args... ) ) ); + } + template void error( fmt::format_string format, Args&&... args ) { if ( thread_index != 0 ) return; - set_error( fmt::vformat( format, fmt::make_format_args( args... ) ) ); + set_error( error_level_e::TRIVIAL, fmt::vformat( format, fmt::make_format_args( args... ) ) ); } void abort(); @@ -821,7 +840,7 @@ struct sim_t : private sc_thread_t } private: - void set_error(std::string error); + void set_error( error_level_e level, std::string error ); void do_pause(); void print_spell_query(); void enable_debug_seed(); diff --git a/engine/util/util.cpp b/engine/util/util.cpp index 587e94e1d38..8ce087b8c3d 100644 --- a/engine/util/util.cpp +++ b/engine/util/util.cpp @@ -2767,6 +2767,21 @@ const char* util::trait_definition_op_string( trait_definition_op op ) return "unk"; } } + +const char* util::error_level_string( error_level_e level ) +{ + switch ( level ) + { + case error_level_e::TRIVIAL: return "Trivial"; + case error_level_e::MODERATE: return "Moderate"; + case error_level_e::SEVERE: return "Severe"; + case error_level_e::FIGHT_STYLE: return "Invalid Fight Style"; + case error_level_e::TALENT_HASH: return "Invalid Talent String"; + case error_level_e::WORK_IN_PROGRESS: return "Work-in-Progress"; + default: return "Unknown"; + } +} + /// Textual representation of rppm scaling bitfield std::string util::rppm_scaling_string( unsigned s ) { diff --git a/engine/util/util.hpp b/engine/util/util.hpp index 7f0ff855084..1e48b9e0908 100644 --- a/engine/util/util.hpp +++ b/engine/util/util.hpp @@ -92,6 +92,7 @@ const char* action_energize_type_string( action_energize energize_type ); const char* action_type_string( action_e type ); const char* talent_tree_string( talent_tree type ); const char* trait_definition_op_string( trait_definition_op op ); +const char* error_level_string( error_level_e level ); std::string rppm_scaling_string ( unsigned ); std::string profile_source_string( profile_source ); diff --git a/qt/MainWindow.cpp b/qt/MainWindow.cpp index fcdfffffa82..7b925bf2f2c 100644 --- a/qt/MainWindow.cpp +++ b/qt/MainWindow.cpp @@ -495,7 +495,7 @@ void SC_MainWindow::deleteSim( std::shared_ptr& sim, SC_TextEdit* append_ if ( sim ) { std::list files; - std::vector errorListCopy( sim->error_list ); + std::vector errorListCopy( sim->error_list ); files.push_back( sim->output_file_str ); files.push_back( sim->html_file_str ); files.push_back( sim->json_file_str ); @@ -734,9 +734,9 @@ void SC_MainWindow::importFinished() simulateTab->append_Text( QString( "# " ) + importThread->error ); } - for ( const std::string& error : import_sim->error_list ) + for ( const auto& error : import_sim->error_list ) { - simulateTab->append_Text( QString( "# " ) + QString::fromStdString( error ) ); + simulateTab->append_Text( QString( "# " ) + QString::fromStdString( error.second ) ); } deleteSim( import_sim, simulateTab->current_Text() ); } diff --git a/qt/sc_SimulationThread.cpp b/qt/sc_SimulationThread.cpp index b08a5f09743..8156bfdf572 100644 --- a/qt/sc_SimulationThread.cpp +++ b/qt/sc_SimulationThread.cpp @@ -88,13 +88,13 @@ void SC_SimulateThread::run() else { error_category = tr( "Simulation runtime error" ); - range::for_each( sim->error_list, [ this ]( const std::string& str ) { + range::for_each( sim->error_list, [ this ]( const auto& error ) { if ( !error_str.isEmpty() ) { error_str += "\n"; } - error_str += QString::fromStdString( str ); + error_str += QString::fromStdString( error.second ); } ); } } @@ -104,13 +104,13 @@ void SC_SimulateThread::run() error_category = tr( "Simulation runtime error" ); std::string error_str_; print_exception( error_str_, e ); - range::for_each( sim->error_list, [ this ]( const std::string& str ) { + range::for_each( sim->error_list, [ this ]( const auto& error ) { if ( !error_str.isEmpty() ) { error_str += "\n"; } - error_str += QString::fromStdString( str ); + error_str += QString::fromStdString( error.second ); } ); error_str += QString::fromStdString( error_str_ ); }