1
0
Fork 0

Add: [Script] GetExtraLastError and GetExtraLastErrorString

Allow scripts to get the extra error message of their last command.

Allow DoCommand and a few others to set extra error messages upon returning result.

Add regression tests.
pull/12269/head
SamuXarick 2024-03-10 23:09:44 +00:00
parent 95f8fc983b
commit ebe5c114dd
12 changed files with 85 additions and 4 deletions

View File

@ -1828,6 +1828,17 @@ function Regression::Vehicle()
print(" GetLastErrorString(): " + AIError.GetLastErrorString());
print(" SendVehicleToDepot(): " + AIVehicle.SendVehicleToDepot(13));
print(" GetLastErrorString(): " + AIError.GetLastErrorString());
print(" BuildVehicle(): " + AIVehicle.BuildVehicle(33417, 116));
print(" AppendOrder(): " + AIOrder.AppendOrder(20, 33421, AIOrder.OF_NONE));
print(" GetLastError(): " + AIError.GetLastError());
print(" GetLastErrorString(): " + AIError.GetLastErrorString());
print(" GetExtraLastError(): " + AIError.GetExtraLastError());
print(" GetExtraLastErrorString(): " + AIError.GetExtraLastErrorString());
print(" SellVehicle(): " + AIVehicle.SellVehicle(20));
print(" GetLastError(): " + AIError.GetLastError());
print(" GetLastErrorString(): " + AIError.GetLastErrorString());
print(" GetExtraLastError(): " + AIError.GetExtraLastError());
print(" GetExtraLastErrorString(): " + AIError.GetExtraLastErrorString());
local list = AIVehicleList();
local in_depot = AIVehicleList(AIVehicle.IsInDepot);

View File

@ -9546,6 +9546,17 @@ ERROR: IsEnd() is invalid as Begin() is never called
GetLastErrorString(): ERR_VEHICLE_NOT_IN_DEPOT
SendVehicleToDepot(): false
GetLastErrorString(): ERR_UNKNOWN
BuildVehicle(): 20
AppendOrder(): false
GetLastError(): 1
GetLastErrorString(): ERR_UNKNOWN
GetExtraLastError(): 1
GetExtraLastErrorString(): ERR_UNKNOWN
SellVehicle(): true
GetLastError(): 0
GetLastErrorString(): ERR_NONE
GetExtraLastError(): 0
GetExtraLastErrorString(): ERR_NONE
--VehicleList--
Count(): 5
@ -9588,7 +9599,7 @@ ERROR: IsEnd() is invalid as Begin() is never called
13 => 5490
12 => 5489
CurrentSpeed ListDump:
12 => 27
12 => 31
17 => 0
16 => 0
14 => 0
@ -9763,9 +9774,9 @@ ERROR: IsEnd() is invalid as Begin() is never called
--Valuate() with excessive CPU usage--
Your script made an error: excessive CPU usage in valuator function
*FUNCTION [unknown()] regression/main.nut line [2065]
*FUNCTION [unknown()] regression/main.nut line [2076]
*FUNCTION [Valuate()] NATIVE line [-1]
*FUNCTION [Start()] regression/main.nut line [2066]
*FUNCTION [Start()] regression/main.nut line [2077]
[id] 0
[this] TABLE
@ -9774,7 +9785,7 @@ Your script made an error: excessive CPU usage in valuator function
[this] INSTANCE
Your script made an error: excessive CPU usage in valuator function
*FUNCTION [Start()] regression/main.nut line [2066]
*FUNCTION [Start()] regression/main.nut line [2077]
[Infinite] CLOSURE
[list] INSTANCE

View File

@ -21,6 +21,8 @@
* \li AIEventVehicleCrashed::GetVictims
* \li AIEventCompanyRenamed
* \li AIEventPresidentRenamed
* \li AIError::GetExtraLastError
* \li AIError::GetExtraLastErrorString
*
* \b 14.0
*

View File

@ -21,6 +21,8 @@
* \li GSEventVehicleCrashed::GetVictims
* \li GSEventCompanyRenamed
* \li GSEventPresidentRenamed
* \li GSError::GetExtraLastError
* \li GSError::GetExtraLastErrorString
*
* \b 14.0
*

View File

@ -23,11 +23,21 @@ ScriptError::ScriptErrorMapString ScriptError::error_map_string = ScriptError::S
return ScriptObject::GetLastError();
}
/* static */ ScriptErrorType ScriptError::GetExtraLastError()
{
return ScriptObject::GetExtraLastError();
}
/* static */ std::optional<std::string> ScriptError::GetLastErrorString()
{
return (*error_map_string.find(ScriptError::GetLastError())).second;
}
/* static */ std::optional<std::string> ScriptError::GetExtraLastErrorString()
{
return (*error_map_string.find(ScriptError::GetExtraLastError())).second;
}
/* static */ ScriptErrorType ScriptError::StringToError(StringID internal_string_id)
{
StringIndexInTab index = GetStringIndex(internal_string_id);

View File

@ -21,6 +21,7 @@
#define EnforcePrecondition(returnval, condition) \
if (!(condition)) { \
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED); \
ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN); \
return returnval; \
}
@ -33,6 +34,7 @@
#define EnforcePreconditionCustomError(returnval, condition, error_code) \
if (!(condition)) { \
ScriptObject::SetLastError(error_code); \
ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN); \
return returnval; \
}
@ -44,6 +46,7 @@
#define EnforcePreconditionEncodedText(returnval, string) \
if (string.empty()) { \
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED); \
ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN); \
return returnval; \
}
@ -60,6 +63,7 @@
#define EnforceCompanyModeValid_Void() \
if (!ScriptCompanyMode::IsValid()) { \
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY); \
ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN); \
return; \
}
@ -83,6 +87,7 @@
#define EnforceDeityOrCompanyModeValid_Void() \
if (!(ScriptCompanyMode::IsDeity() || ScriptCompanyMode::IsValid())) { \
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY); \
ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN); \
return; \
}
@ -190,12 +195,24 @@ public:
*/
static ScriptErrorType GetLastError();
/**
* Get the extra last error.
* @return An ErrorMessages enum value.
*/
static ScriptErrorType GetExtraLastError();
/**
* Get the last error in string format (for human readability).
* @return An ErrorMessage enum item, as string.
*/
static std::optional<std::string> GetLastErrorString();
/**
* Get the extra last error in string format (for human readability).
* @return An ErrorMessage enum item, as string.
*/
static std::optional<std::string> GetExtraLastErrorString();
/**
* Get the error based on the OpenTTD StringID.
* @api -all

View File

@ -150,11 +150,21 @@ ScriptObject::ActiveInstance::~ActiveInstance()
GetStorage()->last_error = last_error;
}
/* static */ void ScriptObject::SetExtraLastError(ScriptErrorType extra_last_error)
{
GetStorage()->extra_last_error = extra_last_error;
}
/* static */ ScriptErrorType ScriptObject::GetLastError()
{
return GetStorage()->last_error;
}
/* static */ ScriptErrorType ScriptObject::GetExtraLastError()
{
return GetStorage()->extra_last_error;
}
/* static */ void ScriptObject::SetLastCost(Money last_cost)
{
GetStorage()->last_cost = last_cost;
@ -286,6 +296,7 @@ std::tuple<bool, bool, bool, bool> ScriptObject::DoCommandPrep()
if (!ScriptCompanyMode::IsDeity() && !ScriptCompanyMode::IsValid()) {
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY);
ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN);
return { true, estimate_only, asynchronous, networking };
}
@ -300,11 +311,13 @@ bool ScriptObject::DoCommandProcessResult(const CommandCost &res, Script_Suspend
/* We failed; set the error and bail out */
if (res.Failed()) {
SetLastError(ScriptError::StringToError(res.GetErrorMessage()));
SetExtraLastError(ScriptError::StringToError(res.GetExtraErrorMessage()));
return false;
}
/* No error, then clear it. */
SetLastError(ScriptError::ERR_NONE);
SetExtraLastError(ScriptError::ERR_NONE);
/* Estimates, update the cost for the estimate and be done */
if (estimate_only) {

View File

@ -174,11 +174,21 @@ protected:
*/
static void SetLastError(ScriptErrorType last_error);
/**
* Set the DoCommand extra last error.
*/
static void SetExtraLastError(ScriptErrorType extra_last_error);
/**
* Get the DoCommand last error.
*/
static ScriptErrorType GetLastError();
/**
* Get the DoCommand extra last error.
*/
static ScriptErrorType GetExtraLastError();
/**
* Set the road type.
*/

View File

@ -52,6 +52,7 @@ SQInteger ScriptPriorityQueue::Pop(HSQUIRRELVM vm)
{
if (this->IsEmpty()) {
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED);
ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN);
sq_pushnull(vm);
return 1;
}
@ -70,6 +71,7 @@ SQInteger ScriptPriorityQueue::Peek(HSQUIRRELVM vm)
{
if (this->IsEmpty()) {
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED);
ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN);
sq_pushnull(vm);
return 1;
}

View File

@ -305,6 +305,7 @@
uint32_t townnameparts;
if (!GenerateTownName(ScriptObject::GetRandomizer(), &townnameparts)) {
ScriptObject::SetLastError(ScriptError::ERR_NAME_IS_NOT_UNIQUE);
ScriptObject::SetExtraLastError(ScriptError::ERR_UNKNOWN);
return false;
}

View File

@ -759,6 +759,7 @@ bool ScriptInstance::DoCommandCallback(const CommandCost &result, const CommandD
if (result.Failed()) {
ScriptObject::SetLastError(ScriptError::StringToError(result.GetErrorMessage()));
ScriptObject::SetExtraLastError(ScriptError::StringToError(result.GetExtraErrorMessage()));
} else {
ScriptObject::IncreaseDoCommandCosts(result.GetCost());
ScriptObject::SetLastCost(result.GetCost());

View File

@ -51,6 +51,7 @@ private:
CommandCost costs; ///< The costs the script is tracking.
Money last_cost; ///< The last cost of the command.
ScriptErrorType last_error{}; ///< The last error of the command.
ScriptErrorType extra_last_error{}; ///< The extra last error of the command.
bool last_command_res; ///< The last result of the command.
CommandDataBuffer last_data; ///< The last data passed to a command.