Improve handling of error responses

This page is a capture in the next bucket of the product backlog — a pre-sprint idea, not yet pulled into a sprint as a story.

As per Gemini code review:

Certainly. Point #2 from the review of `CurrencyHistoryDialog.cpp` addressed
the potential complexity of error checking by suggesting that relying on the
specific response message type is **fragile**.

The goal is to move from:

1.  Client sends **Request A**.
2.  Server returns **Response A** (Success) OR **Error Response** (Failure) OR
    **Response B** (Unexpected success type).
3.  Client checks: *Is the message type exactly **Response A**?*

to a more robust pattern where the client checks for a generic failure response
first.

-----

## 🐞 Fragile Error Check (Current Code)

The current code in `loadHistory` checks for success by expecting *only* the
specific success message type:

```cpp
// Current Fragile Logic
if (result->header().type != comms::protocol::message_type::get_currency_history_response) {
    onHistoryLoadError(QString("Server does not support currency history (received message type %1)")
        .arg(static_cast<int>(result->header().type)));
    return;
}
```

This logic has two main problems:

1.  **Hiding Server Errors:** If the server returns a generic protocol error
    (`message_type::error_response`) because, for example, the client's session
    timed out, the client logs a misleading message: "Server does not support
    currency history." It should be reporting the actual error message sent by
    the server.
2.  **Lack of Standardization:** Every client method needs to implement its own
    logic to handle unexpected types.

-----

## 🛠️ Suggested Improvement: Standardized Error Handling

The improvement is to check for a generic **`error_response`** message type
first, and report its payload/message, before attempting to deserialize the
successful response.

Assuming your system has a standard `error_response` message:

```cpp
void CurrencyHistoryDialog::handleHistoryResponse(const HistoryResult& result) {
    if (!result) {
        onHistoryLoadError(QString::fromStdString(result.error()));
        return;
    }

    // 1. Check for a generic server-side error response
    if (result->header().type == comms::protocol::message_type::error_response) {
        // Assume error_response contains a readable message payload
        auto error_response = risk::messaging::error_response::deserialize(result->payload());
        if (error_response) {
            onHistoryLoadError(QString::fromStdString(error_response->message));
        } else {
            onHistoryLoadError("Server returned a malformed error response.");
        }
        return;
    }

    // 2. Check for the specific SUCCESS response type
    if (result->header().type == comms::protocol::message_type::get_currency_history_response) {
        auto response = risk::messaging::get_currency_history_response::deserialize(result->payload());

        if (!response || !response->success) {
            // Handle success=false within the expected response type
            onHistoryLoadError(QString::fromStdString(response ? response->message : "Invalid or failed history response."));
            return;
        }

        history_ = std::move(response->history);
        onHistoryLoaded();
        return;
    }

    // 3. Handle truly unexpected message type
    onHistoryLoadError(QString("Received unexpected message type %1 from server.")
        .arg(static_cast<int>(result->header().type)));
}
```

By standardizing the **`error_response`** type, the client can always extract
and display the relevant server-side failure reason, leading to much clearer
logging and user feedback.

Emacs 29.1 (Org mode 9.6.6)