Loud and silent software errors

10 listopada 2022
Jakub Rojek Jakub Rojek
Photo by Sound On from Pexels (https://www.pexels.com/pl-pl/zdjecie/zdjecie-portretowe-kobiety-w-zoltej-koszulce-robi-znak-shh-stojac-przed-niebieskim-tle-3761018/)
Kategorie: Branża, Programowanie

Błędy w oprogramowaniu zdarzają się najlepszym i w każdym systemie IT. Niezależnie od tego, ile testów przeprowadzi zespół techniczny, ile czasu poświęci na weryfikację i walidację różnych fragmentów, ile par oczu będzie patrzeć pod różnymi kątami na aplikację, zawsze coś niedobrego się przedostanie. Oczywiście, nie zawsze są to błędy poważne, dyskwalifikujące aplikację w oczach użytkowników. Mało tego - czasami nie są to niedoróbki, o których wiadomo było od początku, że takie będą, gdyż mogą wynikać z niezrozumienia, braku komunikacji lub zmian w specyfikacji czy oczekiwaniach klienta. Tym niemniej, zawsze coś się przebije na produkcję, nawet w ogromnych systemach informatycznych (tak, Facebook czy Google też mają błędy).

Nie jest to więc optymistyczna wizja i choć siłą rzeczy w "nieruchomym" pod kątem wymagań oprogramowaniu kiedyś wszystkie błędy zostaną poprawione, to po pierwsze, rzadko kiedy oprogramowanie nie ulega zmianom funkcjonalnym, po drugie poprawki mogą ujawnić inne niedoskonałości, a po trzecie - nie wszystko opłaca się korygować. Brzmi to bardzo dziwnie i niepokojąco, ale jeśli błąd w aplikacji nie stwarza sytuacji, w której użytkownik dostaje wyniki niezgodne z prawdą (mogące zaburzyć mu pracę), a "jedynie" czyni oprogramowanie trochę nieintuicyjnym i w dodatku poprawka zajmuje więcej czasu, to często klient z wykonawcą ustalają zaniechanie modyfikacji lub odłożenie jej na bliżej nieokreśloną przyszłość (na przykład za pomocą Feedybacky'ego). Oczywiście, nie dotyczy to błędów, które szkodzą wynikom lub sprawiają, że aplikacja działa nieprawidłowo - w takim przypadku trzeba się tym zająć lub, jeszcze lepiej, nie dopuścić do takiej sytuacji.

Natomiast tematem dzisiejszego tekstu jest uzmysłowienie sobie faktu, że istnieją dwa typy błędów. Naturalnie, można podzielić je według wielu sposobów kategoryzacji i pod kilkoma kątami, jednak nas będzie interesować to, jak "głośno" dają o sobie znać. Mamy zatem błędy głośne i ciche. Zapraszam na felieton.

Z jednej strony może to być określane przez to, czy daną niedoróbkę łatwo zauważyć. Istnieją błędy, które wręcz "krzyczą", wyświetlając bardzo enigmatyczne, ale doskonale widoczne komunikaty (niezaprogramowane wcześniej przez deweloperów) lub po prostu wyraźnie pokazujące, że coś z aplikacją jest nie tak poprzez nieprezentujące się dobrze wyniki (np. puste listy rozwijane, które powinny być pełne opcji). Jeśli taka sytuacja występuje, to, oczywiście, nie świadczy to najlepiej o oprogramowaniu - jawnie widoczne błędy powinny ujawnić się w trakcie wewnętrznych testów i zostać poprawione na tyle wcześnie, aby jak najmniejsza liczba użytkowników się na nie natknęła. Natomiast można wyróżnić tutaj jeszcze jedną kwestię - to, w jaki sposób można odtworzyć błąd.

Jeśli droga prowadząca do sytuacji, w której dana niedoróbka się ujawnia, jest znana i łatwa do zdefiniowania, to... bardzo dobrze. Co prawda, nadal tym bardziej nie rozgrzesza to programistów i testerów (bo przecież powinni wcześniej taką drogą zbadać), ale za to łatwo zweryfikować tę sytuację i zidentyfikować źródło problemu. Dużo gorzej, gdy błąd występuje w specyficznych sytuacjach, np. po wybraniu niestandardowych warunków z grona wielu dostępnych. Dotyczy to szczególnie rozbudowanych systemów z formularzami o bardzo dużej liczbie opcji, do których można się dostać z różnych miejsc. Nie ukrywajmy - przy krótkich terminach na dostarczenie oprogramowanie nie sposób przetestować każdą kombinację danych (mimo że software house zawsze się stara), a jeszcze trudniej przewidzieć, które ścieżki będą najczęściej wykorzystywane przez użytkowników lub najbardziej dla nich priorytetowe. Oczywiście, ktoś powie, że to bardzo proste - wystarczy z tymi odbiorcami systemu lub klientem porozmawiać. Jednak z doświadczenia wiemy, że nie zawsze strony mogą wszystko przewidzieć bez przeklikania aplikacji, a poza tym istnieje jeszcze tzw. biznesowa wiedza ukryta, czyli to, co klient wie o swoim środowisku, ale nie wie, że dla zespołu IT jest to niejasne, więc nie widzi potrzeby o tym mówić. To bardziej złożony temat i w kontekście tego tekstu może skutkować tym, że coś, co programistom wydawało się mało znaczącym przypadkiem, nie w pełni zweryfikowanym z uwagi na brak czasu, dla klienta staje się pierwsza rzeczą, jaką wypróbuje i znajdzie błąd, tym samym nastawiając się negatywnie do wykonawcy.

Podsumowując ten fragment, jeśli istnieje jakakolwiek skuteczna i powtarzalna droga do ujawnienia błędnego wykonania się programu, to mamy świetną sytuację. Gorzej, jeśli taki "algorytm" nie jest znany lub niedoróbka pojawia się losowo. Oczywiście, rzadko ma to miejsce faktycznie losowo, ale w kuluarach branży IT istnieje pojęcie błędu bizantyjskiego, czyli takiego, który czasem jest widoczny, a w pozornie identycznej sytuacji nagle nie występuje (zazwyczaj tak się dzieje, gdy klient chce pokazać ten błąd u siebie przy reprezentacie firmy IT). Jest to niesamowicie frustrujące, gdyż nie sposób "złapać" taką sytuację i skutecznie poprawić kod. Powody egzystencji błędów bizantyjskich mogą być przeróżne - oto kilka z nich:

  • specyficzne środowisko uruchomieniowe (np. klient ma zainstalowane konkretne wtyczki w przeglądarce lub korzysta z systemu w danej wersji),
  • zbyt wolne połączenie internetowe, przez co jeden fragment oprogramowania nie ładuje się w określonym czasie,
  • problemy z wielowątkowością (tzw. wyścig wątków lub - w świecie internetowym - żądań),
  • konkretne parametry konfiguracyjne na serwerze,
  • problemy z przepełnieniem pamięci.

Prawda jest taka, że tego typu niedoskonałości mogą być spowodowane nie jedną, ale kombinacją wielu rzeczy, które wpływają na siebie jak kostki domina i dopiero odtworzenie całego ciągu zdarzeń sprawia, że programiści mogą cokolwiek poradzić. Jednak odkrycie takiego szeregu czynników jest zwykle bardzo trudne i nie pomaga tutaj fakt, że sama poprawka może zająć dosłownie chwilę. Klient i tak będzie sfrustrowany i pokazywał, że u niego nie działa i "co z tego, że działa u programistów".

Natomiast w językach kompilowanych lub prekompilowanych (np. C++, Java), pojęcie głośnych i cichych błędów może być rozumiane jeszcze inaczej. Głośne to te, które widać już na etapie kompilacji i nie sposób je przeoczyć lub - jeśli już uda sie je uruchomić - podczas działania programu wyświetlają znaczący komunikat użytkownikowi na ekranie bądź w logach (najczęsciej w formie tzw. stosu wywołań (ang. stack trace). Z kolei ciche błędy nie zgłaszają swojego wystąpienia - pozostają one "w ukryciu", wyświetlając złe wyniki lub nie wykonując wszystkich potrzebnych operacji w tle. To drugie jest szczególnie niebezpieczne, gdyż sprawia, że o takich niedoróbkach wszyscy (użytkownicy i programiści) dowiadują się po czasie, kiedy tak naprawdę nie wiadomo, w jakim momencie i skąd pojawiła się niezgodność w danych. To właśnie największy problem z cichymi problemami - trudno zauważyć w ogóle ich wystąpienie, a jeszcze trudniej zidentyfikować, co jest ich powodem.

Oczywiście, ten felieton nie ma na celu zdjęcia odpowiedzialności z programistów, gdyż to zespół IT jest odpowiedzialny za takie przygotowanie oprogramowania, aby rzeczywiście pomagał w pracy, a nie dostarczał nowych powodów do zmartwień lub wręcz paraliżował funkcjonowanie firmy. Bardziej tym tekstem chciałem zasygnalizować, że błąd błędowi nierówny i niezależnie od użytych narzędzi nie zawsze można wykryć je zawczasu (choć i tak znakomitej większości klient nigdy nie ujrzy), a niektóe jeszcze trudniej prześledzić i znaleźć rozwiązanie na wszystkie przypadki. Wraz z rozwojem technologii aplikacje stają się coraz bardziej rozbudowane i niestety - oznacza to, że jest w nich więcej miejsca na dziwne zachowania.

Pozdrawiam i dziękuję - Jakub Rojek.

Lubimy pisać, nawet bardzo, ale na co dzień tworzymy aplikacje webowe i mobilne. Sprawdź niektóre z wykonanych przez programów.

O autorze

Jakub Rojek

Główny programista i współwłaściciel Wilda Software, z wieloletnim doświadczeniem w tworzeniu i rozwoju oprogramowania, ale także w pisaniu tekstów na różnorakich blogach. Zaprawiony w boju analityk i architekt systemów IT. Jednocześnie absolwent Politechniki Poznańskiej i okazjonalny prowadzący zajęcia na tej uczelni. W wolnych chwilach oddaje się graniu w gry wideo (głównie w karcianki), czytaniu książek, oglądaniu futbolu amerykańskiego i e-sportu, odkrywaniu cięższej muzyki oraz wytykaniu innym błędów językowych.

Jakub Rojek