diff --git a/changelog.md b/changelog.md index c321d307b8..6b9db18cbb 100644 --- a/changelog.md +++ b/changelog.md @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - [Fix missing error of invalid inbound request parameter for forward() method](https://github.com/ballerina-platform/ballerina-standard-library/issues/311) - [Fix HTTP Circuit Breaker failure when status codes are not provided in the configuration](https://github.com/ballerina-platform/ballerina-standard-library/issues/339) - [Fix HTTP FailOver client failure when status codes are overridden by an empty array](https://github.com/ballerina-platform/ballerina-standard-library/issues/1598) +- [Fix already built incompatible payload thrown error](https://github.com/ballerina-platform/ballerina-standard-library/issues/1600) ### Changed - Rename `http:ListenerLdapUserStoreBasicAuthProvider` as `http:ListenerLdapUserStoreBasicAuthHandler` diff --git a/http-ballerina-tests/tests/service_native_in_response_native_function_negative.bal b/http-ballerina-tests/tests/service_native_in_response_native_function_negative.bal index 8931ed0195..da8ab9a46d 100644 --- a/http-ballerina-tests/tests/service_native_in_response_native_function_negative.bal +++ b/http-ballerina-tests/tests/service_native_in_response_native_function_negative.bal @@ -173,3 +173,63 @@ function negativeTestAddCookieWithInvalidMaxAge() { res.addCookie(cookie); test:assertEquals(res.getCookies().length(), 0, msg = "Output mismatched"); } + +listener http:Listener inResponseCachedPayloadListener = new(inResponseCachedPayloadTestPort); +listener http:Listener inResponseCachedPayloadBEListener = new(inResponseCachedPayloadTestBEPort); +http:Client inRespCacheTestClient = check new("http://localhost:" + inResponseCachedPayloadTestPort.toString()); + +service / on inResponseCachedPayloadListener { + resource function get checkJson() returns json|error { + http:Client diseaseEndpoint = check new ("http://localhost:" + inResponseCachedPayloadTestBEPort.toString()); + http:Response resp = check diseaseEndpoint -> get("/getXml"); + byte[] b = check resp.getBinaryPayload(); // represents cache behaviour + return resp.getJsonPayload(); + } + + resource function get checkXml() returns xml|error { + http:Client diseaseEndpoint = check new ("http://localhost:" + inResponseCachedPayloadTestBEPort.toString()); + http:Response resp = check diseaseEndpoint -> get("/getJson"); + byte[] b = check resp.getBinaryPayload(); // represents cache behaviour + return resp.getXmlPayload(); + } +} + +service / on inResponseCachedPayloadBEListener { + resource function get getXml(http:Caller caller) { + http:Response response = new; + xml xmlStr = xml `Ballerina`; + response.setXmlPayload(xmlStr); + error? result = caller->respond(response); + } + + resource function get getJson(http:Caller caller) { + http:Response response = new; + json jsonStr = {"Ballerina" : "hello"}; + response.setJsonPayload(jsonStr); + error? result = caller->respond(response); + } +} + +@test:Config {} +function testInRespGetJsonWhenAlreadyBuildBlobNegative() { + http:Response|error response = inRespCacheTestClient->get("/checkJson"); + if (response is http:Response) { + test:assertEquals(response.statusCode, 500, msg = "Found unexpected output"); + assertTextPayload(response.getTextPayload(), "Error occurred while retrieving the json payload from " + + "the response"); + } else { + test:assertFail(msg = "Found unexpected output type: " + response.message()); + } +} + +@test:Config {} +function testInRespGetXmlWhenAlreadyBuildBlobNegative() { + http:Response|error response = inRespCacheTestClient->get("/checkXml"); + if (response is http:Response) { + test:assertEquals(response.statusCode, 500, msg = "Found unexpected output"); + assertTextPayload(response.getTextPayload(), "Error occurred while retrieving the xml payload from " + + "the response"); + } else { + test:assertFail(msg = "Found unexpected output type: " + response.message()); + } +} diff --git a/http-ballerina-tests/tests/test_service_ports.bal b/http-ballerina-tests/tests/test_service_ports.bal index ac7e4696e8..4bf3ccd46d 100644 --- a/http-ballerina-tests/tests/test_service_ports.bal +++ b/http-ballerina-tests/tests/test_service_ports.bal @@ -118,6 +118,8 @@ const int cBClientWithoutStatusCodesTestPort1 = 9569; const int cBClientWithoutStatusCodesTestPort2 = 9570; const int foClientWithoutStatusCodeTestPort1 = 9571; const int foClientWithoutStatusCodeTestPort2 = 9572; +const int inResponseCachedPayloadTestPort = 9573; +const int inResponseCachedPayloadTestBEPort = 9574; //HTTP2 const int serverPushTestPort1 = 9601; diff --git a/http-native/src/main/java/org/ballerinalang/net/http/nativeimpl/ExternHttpDataSourceBuilder.java b/http-native/src/main/java/org/ballerinalang/net/http/nativeimpl/ExternHttpDataSourceBuilder.java index b0ddcdc64f..185208e678 100644 --- a/http-native/src/main/java/org/ballerinalang/net/http/nativeimpl/ExternHttpDataSourceBuilder.java +++ b/http-native/src/main/java/org/ballerinalang/net/http/nativeimpl/ExternHttpDataSourceBuilder.java @@ -76,7 +76,7 @@ public static Object getNonBlockingByteArray(Environment env, BObject entityObj) balFuture = env.markAsync(); constructNonBlockingDataSource(balFuture, entityObj, SourceType.BLOB); } catch (Exception exception) { - notifyError(balFuture, exception, "blob"); + return notifyError(balFuture, exception, "blob"); } return null; } @@ -96,7 +96,7 @@ public static Object getNonBlockingJson(Environment env, BObject entityObj) { balFuture = env.markAsync(); constructNonBlockingDataSource(balFuture, entityObj, SourceType.JSON); } catch (Exception exception) { - notifyError(balFuture, exception, "json"); + return notifyError(balFuture, exception, "json"); } return null; } @@ -116,7 +116,7 @@ public static Object getNonBlockingText(Environment env, BObject entityObj) { balFuture = env.markAsync(); constructNonBlockingDataSource(balFuture, entityObj, SourceType.TEXT); } catch (Exception exception) { - notifyError(balFuture, exception, "text"); + return notifyError(balFuture, exception, "text"); } return null; } @@ -137,7 +137,7 @@ public static Object getNonBlockingXml(Environment env, BObject entityObj) { balFuture = env.markAsync(); constructNonBlockingDataSource(balFuture, entityObj, SourceType.XML); } catch (Exception exception) { - notifyError(balFuture, exception, "xml"); + return notifyError(balFuture, exception, "xml"); } return null; } @@ -210,9 +210,13 @@ public void onError(Exception ex) { }); } - private static void notifyError(Future balFuture, Exception exception, String type) { + private static Object notifyError(Future balFuture, Exception exception, String type) { BError error = (BError) createError(exception, type); - setReturnValuesAndNotify(balFuture, error); + if (balFuture != null) { + setReturnValuesAndNotify(balFuture, error); + return null; + } + return error; } private static void createErrorAndNotify(Future balFuture, String errMsg) {