当返回是联合类型时,有效负载数据绑定不起作用?

问题描述 投票:0回答:1

我正在尝试在我的代码中运行访问以下服务。

以下代码段说明了该服务:

import ballerina/http;

type Album readonly & record {|
    string title;
    string artist;
|};

type IdNotFound record {|
    *http:NotFound;
    record {
        string message;
    } body;
|};

table<Album> key(title) albums = table [
    {title: "Blue Train", artist: "John Coltrane"},
    {title: "Jeru", artist: "Gerry Mulligan"}
];

service / on new http:Listener(8022) {

    resource function get album/[string id]() returns Album|IdNotFound {
        if (!albums.hasKey(id)) {
            return {body: {message: "No matching resource found."}};
        }
        return albums.get(id);
    }
}

以下是我在 main.bal 文件中的代码

import ballerina/http;
import ballerina/io;

type Album readonly & record {
    string title;
    string artist;
};

type IdNotFound record {|
    *http:NotFound;
    record {
        string message;
    } body;
|};

public function main() returns error? {
    // Creates a new client with the Basic REST service URL.
    http:Client albumClient = check new ("localhost:8022");

    string id = "Blue Train";
    Album|IdNotFound album = check albumClient->/album/[id];
    io:println("GET request:" + album.toJsonString());
}

当尝试运行此代码时,我在第

Album|IdNotFound album = check albumClient->/album/[id];

行中收到以下错误

线

incompatible type for parameter 'targetType' with inferred typedesc value: expected 'typedesc<(ballerina/http:2.8.0:Response|anydata)>', found 'typedesc<(wso2healthcare/abc:0.2.3:Album|wso2healthcare/abc:0.2.3:IdNotFound)>'(BCE3931)

我可以知道我的代码有什么问题吗?

data-binding ballerina-swan-lake ballerina-http
1个回答
0
投票

您只能绑定响应负载(预计是anydata的子类型)。该错误是因为您还使用 IdNotFound (不是任何数据)来尝试绑定到它。

您可以采取与以下类似的方法。

Album|http:ClientError album = albumClient->/album/[id];

if album is Album {
    string title = album.title;
    io:println("Title: ", title);
    return;
}

if album !is http:ClientRequestError {
    return album;
}

// album is http:ClientRequestError here
// 4xx errors
record {
    string message;
} body = check album.detail().body.ensureType();
io:println("Message: ", body.message);

如果您需要使用规范定义的错误消息结构来包装所有错误,则可以使用 ResponseErrorInterceptor 来更改错误结构,如下所示:

type ErrorDetails record {|
    string timestamp;
    string message;
|};

// This can handle all the interceptable errors
service class ErrorInterceptor {
    *http:ResponseErrorInterceptor;

    // We can access error and the already built response wrt to the error type
    remote function interceptResponseError(error err, http:Response errResponse) returns error {
        // Changing all the errors
        // Construct the spec defined error body
        ErrorDetails errDetails = {
            timestamp: time:utcToString(time:utcNow()),
            message: err.message()
        };
        // Return a default status code error with the error body
        // Set the cause to the original error to maintain the status code
        return error httpscerr:DefaultStatusCodeError("default error", err, body = errDetails);
    }
}

service http:InterceptableService / on new http:Listener(8022) {
    public function createInterceptors() returns ErrorInterceptor {
        return new ErrorInterceptor();
    }

    ...
}
© www.soinside.com 2019 - 2024. All rights reserved.