我正在尝试在我的代码中运行访问以下服务。
以下代码段说明了该服务:
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)
我可以知道我的代码有什么问题吗?
您只能绑定响应负载(预计是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();
}
...
}