Wykrywanie błędów przejściowych w kodzie

Ukończone

Po zapoznaniu się z możliwymi błędami przejściowymi, które mogą wystąpić w aplikacjach firmy, warto dodać kod pozwalający na ich wykrywanie. Każdą aplikację korzystającą z usług zewnętrznych należy tworzyć tak, aby wykrywała problemy w momencie ich wystąpienia. Jeśli usługa oparta na chmurze została dobrze napisana i zaprojektowana, może być oferowana z umową, która zawiera dobrze udokumentowane błędy. Umowa ta udostępnia pewne kroki, które aplikacja może wykonać w celu obsługi błędu i odzyskania sprawności po jego wystąpieniu.

Representational State Transfer (REST) to podejście do pisania aplikacji klienta i serwera. Usługi RESTful są bezstanowe, klient i serwer nie śledzą nawzajem swoich stanów. Żądanie REST jest wysyłane przez klienta i zwracana jest odpowiedź. Żądania REST są zwykle wysyłane za pośrednictwem żądań protokołu HTTP (na przykład GET i POST), więc zwrócona odpowiedź może zawierać standardowe błędy HTTP, na przykład:

  • 404: identyfikator URI jest niedostępny, nie można znaleźć żądanego zasobu na serwerze
  • 408: przekroczenie limitu czasu żądania, klient nie wysłał żądania do serwera na czas
  • 449: zwrócony kod jest specyficzny dla firmy Microsoft i zawiera informacje o kliencie, których można użyć do podjęcia ponownej próby wykonania operacji
  • 503: Usługa tymczasowo nie może obsłużyć otrzymanego żądania
  • 504: przekroczenie limitu czasu bramy, usługi nadrzędne nie mogą odpowiedzieć wystarczająco szybko

Aplikacje firmowe, które korzystają z usług REST, powinny mieć możliwość obsługiwania tych błędów przejściowych. Firma podjęła decyzję o użyciu platformy Azure. W zależności od stosowanych funkcji platforma Azure ma dobrze zdefiniowanego błędy, które muszą być obsługiwane.

Połączenia platformy Azure na platformie ASP.NET mogą otrzymywać odpowiedzi WebExceptionStatus.ConnectionClosed, WebExceptionStatus.Timeout lub WebExceptionStatus.RequestCanceled.

Bazy danych Azure Cosmos DB to usługi RESTful, dlatego mogą zwracać powyższe błędy i określony kod błędu 429, który powiadamia klienta, że liczba żądań jest zbyt duża. Ten błąd może zostać zwrócony, jest przepływność jest zbyt mała albo liczba i rozmiar żądań są zbyt duże.

Usługa Azure SQL Database ma również dobrze zdefiniowane kody błędów, na przykład 40501: Usługa jest obecnie zajęta. Ponów żądanie po X sekundach.

Aplikacja zespołu do czatów implementuje tablicę wirtualną. Użytkownicy mogą zostawiać komunikaty do odczytania dla całego zespołu. Używa ona bazy danych Azure Cosmos DB do przechowywania komunikatów utworzonych za pomocą interfejsu API bazy danych MongoDB. Zespół może szybko tworzyć klientów dla aplikacji do czatów na platformie .NET Core w języku C#, Java i środowisku Node, korzystając z posiadanej już wiedzy na temat bazy danych MongoDB.

Aplikacja do czatów powinna wykrywać następujące typy błędów:

  • Utracone połączenia z usługą Azure Cosmos DB
  • Każda niedostępność usług
  • Obsługa wyjątków zgłaszanych przez inne części aplikacji

Niezależnie od błędu zwróconego przez usługę, aplikacje muszą przechwycić zwrócony błąd, sprawdzić go, a następnie podjąć odpowiednie kroki, aby go obsłużyć. Wszystkie języki programowania mają funkcje dostępne dla deweloperów w celu obsługi błędów w kodzie.

Wykrywanie błędów w kodzie

W języku C# mechanizm wykrywania i obsługi błędów to blok try catch. Można zdefiniować różne sposoby obsługi różnych błędów, określając wyjątek, który chcesz obsługiwać.

    try {

        // Some C# code

    }
    catch (an error) {

        // Some C# code to handle the specific error

    }
    catch (a different error) {

        // Some C# code to handle the specific error

    }

Wszystkie błędy dziedziczą po klasie wyjątku. Bloki catch należy definiować w kolejności od najbardziej specyficznego do najbardziej ogólnego. Ostatni blok catch powinien być podobny do następującego bloku:

    catch (Exception e) {

        // Will always match any exception that is raised

    }

Użycie tego bloku catch umożliwia programowi obsługę nieoczekiwanych błędów i — w razie potrzeby — przeprowadzanie dodatkowego rejestrowania. W firmowej aplikacji do czatów w firmie występują błędy przejściowe, które mogą być zwracane z bazy danych MongoDB:

  • MongoDB.Driver.MongoConnectionException: wystąpił problem z hasłem lub poświadczeniem albo inny problem z bazą danych Mongo DB
  • System.TimeoutException: wystąpił problem z połączeniem z bazą danych

W języku Java mechanizm wykrywania i obsługi błędów to blok try catch. Można zdefiniować liczbę bloków catch, określając wyjątek, który chcesz obsługiwać.

    try {

        // Some JAVA code

    }
    catch (an error) {

        // Some JAVA code to handle the specific error

    }
    catch (a different error) {

        // Some JAVA code to handle the specific error

    }

Wszystkie błędy dziedziczą po klasie wyjątku. Bloki catch należy definiować w kolejności od najbardziej specyficznego do najbardziej ogólnego. Ostatni blok catch powinien być następujący:

    catch (Exception e) {

        // Will always match any exception that is raised

    }

Użycie tego bloku catch umożliwia programowi obsługę nieoczekiwanych błędów i — w razie potrzeby — przeprowadzanie dodatkowego rejestrowania. W firmowej aplikacji do czatów w firmie występują błędy przejściowe, które mogą być zwracane z bazy danych MongoDB:

  • com.mongodb.MongoCommandException: wystąpił problem z połączeniem z bazą danych, nie można wykonać polecenia
  • com.mongodb.MongoSecurityException: wystąpił problem z hasłem lub poświadczeniem albo baza danych jest niedostępna

W środowisku Node mechanizm wykrywania i obsługi błędów zależy od kontekstu. W przypadku kodu synchronicznego jest to blok try catch. Jeśli wyjątek zostanie zgłoszony podczas działania kodu, można zdefiniować liczbę bloków catch, określając wyjątek, który chcesz obsługiwać.

    try {

        //Some javascript code

    }
    catch (error) {

        if (error.code === 'specific error') {

            //Some javascript code to handle the specific error

        } else {

            //Handle all other errors

        }
    }

Środowisko Node zostało jednak zbudowane jako asynchroniczne. Język definiuje pojęcie obietnic, aby obsługiwać błędy występujące w kodzie asynchronicznym. W przypadku wywoływania funkcji asynchronicznej można użyć obietnicy catch(), która zostanie wykonana, jeśli funkcja zwróci błędy.

    async-function-call()
        .then( () => {
            // handle response
            }
        )
        .catch( err => {
            // handle any raised exceptions
            }
        )

W firmowej aplikacji do czatów w firmie występują błędy przejściowe, które mogą być zwracane z bazy danych MongoDB:

  • MongoNetworkError: wystąpił problem z połączeniem z bazą danych
  • MongoError: wystąpił problem z hasłem lub poświadczeniem albo inny problem z bazą danych

Załóżmy, że błąd został wykryty i sklasyfikowany jako przejściowy. Aplikacja musi zdecydować, czy można spróbować ponownie wykonać operację w sposób bezpieczny dla aplikacji i usługi.