Azure SDK for C++ 中的錯誤處理

Azure SDK for C++ 中的錯誤處理主要是透過C++例外狀況來實作。 此方法與標準 C++ 做法一致,並允許在整個 SDK 中清晰的錯誤報告和處理。 當您C++應用程式與 Azure 服務互動時,作業可能會因為各種原因而失敗,例如驗證問題、服務無法使用、無效的要求或資源條件約束。 SDK 會將這些錯誤擷取為例外狀況,以提供失敗的詳細資訊。

例外狀況階層

核心例外狀況類型

適用於C++的 Azure SDK 會使用例外狀況類別的階層,其中最重要的是:

  1. std::runtime_error - 從中繼承 Azure 特定例外狀況的基底 C++ 標準例外狀況。

  2. Azure::Core::RequestFailedException - 衍生自 std::runtime_error,這是所有 Azure 服務要求失敗的基礎例外狀況。 在azure/core/exception.hpp中定義的此例外狀況,會在對 Azure 服務的請求失敗時擲回。 這提供了以下內容:

    • HTTP 狀態代碼
    • 來自服務的錯誤碼
    • 錯誤訊息
    • 進行疑難解答的要求標識碼
    • 原始 HTTP 回應
  3. Azure::Core::OperationCancelledException - 衍生自 std::runtime_error,此例外狀況會在取消作業時擲回,通常是透過內容物件。

  4. Azure::Core::Http::TransportException - 衍生自 Azure::Core::RequestFailedException,此例外狀況會在 HTTP 傳輸層發生錯誤時擲回,例如連線失敗。

  5. Azure::Core::Credentials::AuthenticationException - 衍生自 std::exception,當向 Azure 服務進行驗證失敗時,會擲回此例外狀況。

服務特定的例外狀況類型

不同的 Azure 服務會擴充基底例外狀況類型,以提供服務特定的錯誤資訊:

  1. Azure::Storage::StorageException - 使用其他記憶體特定資訊擴充 RequestFailedException 。 此例外狀況包括:

    • 記憶體特定錯誤碼
    • 回應內容中的其他資訊
    • 失敗儲存操作的詳細資訊
  2. Azure::Messaging::EventHubs::EventHubsException - 事件中樞作業特有的例外狀況。 其中包含:

    • 錯誤條件(Advanced Message Queuing Protocol (AMQP)中的符號值)
    • 錯誤描述
    • 狀態代碼
    • 錯誤是否為暫時性的相關信息

例外狀況的錯誤資訊

類別 RequestFailedException 包含服務失敗的豐富資訊:

class RequestFailedException : public std::runtime_error {
public:
    // The entire HTTP raw response
    std::unique_ptr<Azure::Core::Http::RawResponse> RawResponse;
    
    // The HTTP response code
    Azure::Core::Http::HttpStatusCode StatusCode;
    
    // The HTTP reason phrase from the response
    std::string ReasonPhrase;
    
    // The client request header (x-ms-client-request-id) from the HTTP response
    std::string ClientRequestId;
    
    // The request ID header (x-ms-request-id) from the HTTP response
    std::string RequestId;
    
    // The error code from service returned in the HTTP response
    std::string ErrorCode;
    
    // The error message from the service returned in the HTTP response
    std::string Message;
    
    /* ... constructors and other methods ... */
};

服務特定的例外狀況可以新增額外的欄位。 例如, StorageException 新增 AdditionalInformation:

struct StorageException final : public Azure::Core::RequestFailedException {
    // Some storage-specific information in response body
    std::map<std::string, std::string> AdditionalInformation;
    
    /* ... constructors and other methods ... */
};

例外狀況處理模式和範例

使用錯誤碼

服務例外狀況包含 ErrorCode 值,可用來決定如何處理失敗。 以下是記憶體服務的範例:

try {
    containerClient.Delete();
}
catch (Azure::Storage::StorageException& e) {
    if (e.ErrorCode == "ContainerNotFound") {
        // Ignore the error if the container does not exist
    }
    else {
        // Handle other errors here
    }
}

處理基本例外狀況

在 Azure SDK 中處理例外狀況的基本模式:

try {
    // Perform an Azure SDK operation
    result = client.SomeOperation();
}
catch (Azure::Core::RequestFailedException const& e) {
    std::cout << "Request Failed Exception happened:" << std::endl << e.what() << std::endl;
    if (e.RawResponse) {
        std::cout << "Error Code: " << e.ErrorCode << std::endl;
        std::cout << "Error Message: " << e.Message << std::endl;
    }
    // Handle or rethrow as appropriate
}
catch (std::exception const& e) {
    std::cout << "Other exception: " << e.what() << std::endl;
    // Handle general exceptions
}

處理暫時性錯誤

某些服務,例如事件中樞,提供錯誤是否為暫時性的資訊,允許重試邏輯:

try {
    // EventHubs operation
}
catch (Azure::Messaging::EventHubs::EventHubsException& e) {
    if (e.IsTransient) {
        // Retry the operation after a delay
    }
    else {
        // Handle permanent failure
    }
}

SDK 為暫時性失敗實作內部重試政策,但你可能仍想在應用程式程式碼中處理特定案例。

服務特定的錯誤處理

對於像 Blobs、Files 和 Queues 這類儲存服務,你可以根據錯誤碼和 HTTP 狀態碼來處理錯誤:

try {
    shareClient.Delete();
}
catch (Azure::Storage::StorageException& e) {
    if (e.ErrorCode == "ShareNotFound") {
        // Ignore the error if the file share does not exist
    }
    else if (e.StatusCode == Azure::Core::Http::HttpStatusCode::Conflict) {
        // Handle conflict error (e.g., resource in use)
        std::cout << "Conflict error: " << e.Message << std::endl;
        
        // Check additional information
        for (auto const& info : e.AdditionalInformation) {
            std::cout << info.first << ": " << info.second << std::endl;
        }
    }
    else {
        // Handle other errors based on status code or error code
        std::cout << "Error: " << e.Message << " (Code: " << e.ErrorCode << ")" << std::endl;
    }
}

針對 金鑰保存庫 作業,您可能需要個別處理驗證例外狀況:

try {
    // Key Vault operation
}
catch (Azure::Core::Credentials::AuthenticationException const& e) {
    std::cout << "Authentication Exception happened:" << std::endl << e.what() << std::endl;
    // Handle authentication failure (e.g., invalid credentials)
}
catch (Azure::Core::RequestFailedException const& e) {
    std::cout << "Key Vault Client Exception happened:" << std::endl << e.Message << std::endl;
    // Handle Key Vault specific errors
}

線程安全性考慮

適用於 C++ 的 Azure SDK 保證用戶端實例方法彼此安全且彼此獨立。 這表示您可以在多個線程之間安全地使用用戶端實例,而不需要同步處理。

處理線程之間的例外狀況時,請記住:

  1. 除非正確同步處理,否則線程之間不應該共用例外狀況物件
  2. RequestFailedException包含可建立深層複製的複製建構函式,當需要在線程之間傳遞例外狀況資訊時,可以使用此建構函式