GMS 2.3 - try-catch - łapanie wyjątków
Czwartek, 19 Grudnia 2019, 14:03
Czas czytania 2 minuty, 24 sekundy
Zgodne z GM:
Nowy mechanizm w GMS 2.3, którego brakowało nam wszystkim.
GMS 2.3 pozwoli na łapanie wyjątków (błędów w kodzie) co pozwoli na dalsze działanie naszej gry bez zawieszenia/wyłączenia.
Ot, chociażby kod:
kodvar a = 5 / 0;Normalnie zwraca błąd "Cannot divide by zero". Każdy bowiem wie, że przez zero dzielić się nie da. Gra pokaże ekran błędu z przyciskiem OK i zakończy działanie.
W GMS 2.3 można to jednak obejść:
kodtry {
<statement1>;
<statement2>;
etc...
}
catch(<variable>) {
<statement1>;
<statement2>;
etc...
}gdzie <variable> to nazwa zmiennej, do jakiej trafi struktura z właściwościami błędu:
kod
<variable> = {
message: "<text>",
longMessage: "<text>",
script: "<text>",
stacktrace: ["<text>", "<text>", ...]
};Przykładowo, można pominąć wyskakiwanie okienka z błędem i zamiast tego wyświetlić błąd w konsoli (albo po zmianie kodu zapisywać/wysyłać).
kodvar a = 0, b = 0, c = 0;
try
{
c = a div b;
}
catch( _exception)
{
show_debug_message(_exception.message);
show_debug_message(_exception.longMessage);
show_debug_message(_exception.script);
show_debug_message(_exception.stacktrace);
}
Można też skorzystać z instrukcji finally, aby wykonać kod bez wzgledu na to, czy wyjątek wystąpi czy nie, poprzedzając nią nasz blok kodu:
kodfinally {
<statement1>;
<statement2>;
etc...
}Wskazówka:
Można używać dowolnych kombinacji try+finally, try+catch lub try+catch+finally, ale w takich blokach nie można używać break, continue, exit czy return, gdyż gra się nie skompiluje.
kodvar a = 0, b = 0, c = 0;
try
{
try
{
c = a div b;
}
finally
{
++a;
}
}
catch(_exception)
{
++a;
show_debug_message(_exception.message);
show_debug_message(_exception.longMessage);
show_debug_message(_exception.script);
show_debug_message(_exception.stacktrace);
}
finally
{
show_debug_message("a = " + string(a));
}
Można też użyć funkcji, która złapie wszystkie niezłapane wyjątki aby nie wyświetlać żadnych błędów (ale je logować/wysyłać).
Służy do tego exception_unhandled_handler(user_handler);.
kodexception_unhandled_handler(function(ex)
{
show_debug_message( "----------------------------------------------------------------------");
show_debug_message( "Unhandled exception " + string(ex) );
show_debug_message( "----------------------------------------------------------------------");
if file_exists("crash.txt") file_delete("crash.txt");
var _f = file_text_open_write("crash.txt");
file_text_write_string(_f, string(ex));
file_text_close(_f);
return 0;
}
)W powyższym przykładzie zapisujemy ostatni błąd do pliku (ostatni - gdyż następuje kasowanie pliku gdy już istniał).
Wskazówka:
Użycie return spowoduje, że taki właśnie kod zostanie zwrócony na zakończenie pracy runnera. Nie jest to wymagany parametr
Ot, chociażby kod:
kodvar a = 5 / 0;Normalnie zwraca błąd "Cannot divide by zero". Każdy bowiem wie, że przez zero dzielić się nie da. Gra pokaże ekran błędu z przyciskiem OK i zakończy działanie.
W GMS 2.3 można to jednak obejść:
kodtry {
<statement1>;
<statement2>;
etc...
}
catch(<variable>) {
<statement1>;
<statement2>;
etc...
}gdzie <variable> to nazwa zmiennej, do jakiej trafi struktura z właściwościami błędu:
kod
<variable> = {
message: "<text>",
longMessage: "<text>",
script: "<text>",
stacktrace: ["<text>", "<text>", ...]
};Przykładowo, można pominąć wyskakiwanie okienka z błędem i zamiast tego wyświetlić błąd w konsoli (albo po zmianie kodu zapisywać/wysyłać).
kodvar a = 0, b = 0, c = 0;
try
{
c = a div b;
}
catch( _exception)
{
show_debug_message(_exception.message);
show_debug_message(_exception.longMessage);
show_debug_message(_exception.script);
show_debug_message(_exception.stacktrace);
}
Można też skorzystać z instrukcji finally, aby wykonać kod bez wzgledu na to, czy wyjątek wystąpi czy nie, poprzedzając nią nasz blok kodu:
kodfinally {
<statement1>;
<statement2>;
etc...
}Wskazówka:
Można używać dowolnych kombinacji try+finally, try+catch lub try+catch+finally, ale w takich blokach nie można używać break, continue, exit czy return, gdyż gra się nie skompiluje.
kodvar a = 0, b = 0, c = 0;
try
{
try
{
c = a div b;
}
finally
{
++a;
}
}
catch(_exception)
{
++a;
show_debug_message(_exception.message);
show_debug_message(_exception.longMessage);
show_debug_message(_exception.script);
show_debug_message(_exception.stacktrace);
}
finally
{
show_debug_message("a = " + string(a));
}
Można też użyć funkcji, która złapie wszystkie niezłapane wyjątki aby nie wyświetlać żadnych błędów (ale je logować/wysyłać).
Służy do tego exception_unhandled_handler(user_handler);.
kodexception_unhandled_handler(function(ex)
{
show_debug_message( "----------------------------------------------------------------------");
show_debug_message( "Unhandled exception " + string(ex) );
show_debug_message( "----------------------------------------------------------------------");
if file_exists("crash.txt") file_delete("crash.txt");
var _f = file_text_open_write("crash.txt");
file_text_write_string(_f, string(ex));
file_text_close(_f);
return 0;
}
)W powyższym przykładzie zapisujemy ostatni błąd do pliku (ostatni - gdyż następuje kasowanie pliku gdy już istniał).
Wskazówka:
Użycie return spowoduje, że taki właśnie kod zostanie zwrócony na zakończenie pracy runnera. Nie jest to wymagany parametr