Handling "204 no content" in Spring-Integration - spring-integration

My int-http:outbound-gateway is returning "204 no content" . As a result my UI layer is failing because it is expecting a not null payload. Is there any way to handle this situation in Spring-Integration?

The HttpRequestExecutingMessageHandler does this:
if (this.expectReply) {
...
AbstractIntegrationMessageBuilder<?> replyBuilder = null;
if (httpResponse.hasBody()) {
Object responseBody = httpResponse.getBody();
replyBuilder = (responseBody instanceof Message<?>) ?
this.getMessageBuilderFactory().fromMessage((Message<?>) responseBody) : this.getMessageBuilderFactory().withPayload(responseBody);
}
else {
replyBuilder = this.getMessageBuilderFactory().withPayload(httpResponse);
}
replyBuilder.setHeader(org.springframework.integration.http.HttpHeaders.STATUS_CODE, httpResponse.getStatusCode());
return replyBuilder.copyHeaders(headers).build();
}
return null;
So, if you don't use <int-http:outbound-channel-adapter> you definitely get some reply and there will be that HttpHeaders.STATUS_CODE header with the HttpStatus.NO_CONTENT as value.
As you see the payload of the message depends of the httpResponse.hasBody() and I guess in case of HttpStatus.NO_CONTENT there is really no body. So, payload is a full ResponseEntity.
Now, please, share more info how does it work for you? How do you get a null payload?

Related

How to get the Id of this response and then serialize it?

I need to get the id from a response with a for loop, then make a call and serialize the final result but I don't know how. This is the code:
Http http = new Http();
HTTPResponse response;
HttpRequest request;
String userEmail = 'myemail#mail.com';
request = new HttpRequest();
request.setMethod('GET');
request.setEndpoint('callout:Gmail_API/gmail/v1/users/myemail#mail.com/messages?q=from:anothermail#mail.com');
response = http.send(request);
System.debug(response.getBody());
If I run an "Execute anonymous apex" I get this:
{
"messages": [
{
"id": "17d9fdeb824b97be",
"threadId": "17d9fdeb824b97be"
}
],
"resultSizeEstimate": 1
}
And essentially I need to return that response and get the Id and then make a call with the threadId and serialize it in a list which I have to use it in a Salesforce lightning component later. How do I do that? Thank you in advance.
Please use the below code snippet to get the threadId value.
if(response.getStatusCode() == 200) {
JSONParser parser = JSON.createParser(response.getBody());
while (parser.nextToken() != null) {
if (
(parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
(parser.getText() == 'threadId')
) {
parser.nextToken();
threadId = parser.getText();
}
}
}
If it helps you, please mark it as the best answer to help others as well.

Throwing exceptions on AWS Lambda with Node12.x in Axios catch handlers

I'm having a hard time trying to understand how I can make this function work. I think it stems from me not really understanding 100% how to handle promises, but I've read all the tutorials I can find and I still don't see how I can do this.
The following is a function, which calls an endpoint on an API. When it's successful, it'll return a token for use in future requests. When it fails, I want to throw an exception and completely stop the execution.
I've heard that when throwing in a catch handler like this, then you're thrown exception is handled by a hidden try/catch and this passes to the next catch handler. But this is effectively meaning my exception gets black-holed. Which I've heard is a thing and I've read other questions on this website about that.
The actual example isn't this trivial. But the effective code is still the same, a try/catch wrapped around all the code in question. But any exceptions never land in the right place. Then lambda fails with the exception in question. But it's not handled by the code that I wrote, so the response is wrong. I need to handle the code and output a different reply based on what exception is being thrown. So I change it around, fix up the data, add other related information and return that. But since I'm never landing in the right place. I can never do that.
How could I alter this function, so that it correctly lands in the exception handler I've given? Thanks for your help
let getToken = async () => {
let transport = axios.create({ baseURL, headers: passwordHeaders });
return transport.post('/authorization/login')
.then(response => {
let accessToken = _.get(response, 'data.access_token', null);
if(accessToken !== null){
let base64 = Buffer.from(accessToken, 'base64');
let token = base64.toString('ascii');
return token.split(";").shift().split(":").pop();
}
throw new LoginError(response.statusText, response.status));
})
.catch(error => {
if(_.get(error, 'response.status', 'null') === 403){
throw new UnauthorizedError(error.response.statusText);
}
throw error;
});
}
try{
let token = await getToken();
}catch(error){
console.log("this exception should land here");
}
As mentioned in the problems the main problem is the mix of then style and async/await. If we lean into the async approach we could do the following:
let getToken = async () => {
let transport = axios.create({ baseURL });
try {
const response = await transport.post("/authorization/login");
let accessToken = _.get(response, "data.access_token", null);
if (accessToken !== null) {
let base64 = Buffer.from(accessToken, "base64");
let token = base64.toString("ascii");
return token.split(";").shift().split(":").pop();
}
} catch (e) {
throw e;
}
};
try {
let token = await getToken();
} catch (error) {
console.log("this exception should land here");
}
As getToken is an asynchronous function it returns a Promise, returning within this function equals to using Promise.resolve and throwing equals to Promise.reject. In my case the catch block of getToken does not do anything and getToken gets called from within a try / catch. We might want to delegate error handling to the outer try catch by removing the inner one.

if object is invalid json format - forward contents forward contents anyway - NODEJS

I am currently forwarding cloudwatch alarms to slack using a nodejs lambda function I found on github, however, when it receives a custom alert from one of our customers datacenters, the string is not in a JSON format, so it will not print the alert.
I am looking at rewriting the handleCatchAll() function to handle the string and just forward it to slack in its current format, but am having issues identifying the object.
Below is the code i am trying to edit, I need to write an if statement that will identify the object, say "if JSON.stringify fails, then render the message without JSON.stringify and input its value into 'description'"
var description = ""
if ()
{
else if ()
{
for(key in message) {
var renderedMessage = typeof message[key] === 'object'
? JSON.stringify(message[key])
: message[key]
description = description + "\n" + key + ": " + renderedMessage
}
}
}
You can use this script to convert text input into json if the text is a valid JSON object, or else keep the original text.
const isJSON = str => {
try {
return (JSON.parse(str) && !!str);
} catch (e) {
return false;
}
}
const regulizeRequestBody = body => isJSON(body) ? JSON.parse(body) : body;

validateField client event doen't work properly in Chrome

I'm trying to validate 'vatregnumber' field on the Vendor record,
Here is my sample code. It works in Mozilla but in Chrome it messages infinite loop.
function clientValidateField(type, name, linenum) {
if (name === 'vatregnumber') {
var isValid = validateTaxNum(); // a function returns boolean. If it returns false it gives an alert message. //
return isValid;
}
return true;
}
I agree that this similar question has been asked, but is there any way to slove these kind of troubles

code explanation nodejs expressjs mongoose

i feel a bit embarrassed, can you please kindly explain parts of the code?
For example, I have no idea, what is this part? where can I read more about it?
function parsePostStory(data) {
return {
name : data.name
}
}
What is req.body? Is it json req body?
Why do we declare empty array and why do we return it? Just for the clarity?
Is Story.create just a mongoose method?
The rest of the code is here:
router.post('/stories', function(req, res) {
var validation = validatePostStory(req.body);
if(validation.length > 0) {
return res.badRequestError(validation);
}
var story = parsePostStory(req.body);
Story.create(story, function(err, story) {
if(err) {
console.log(err.message);
return res.internalServerError();
} res.send(story);
});
});
function validatePostStory(data) {
var array = [];
if (!data.name || typeof data.name !== 'String') {
return array.push('name');
}
return array;
}
function parsePostStory(data) {
return {
name : data.name
}
}
Sorry once more for that kind of a question and thanks a ton.
I'm assuming you know how the request-response cycle works with HTTP requests and the client-server interactions with it. If not, Wikipedia Request-Response and Client-Server (Two link limit, otherwise I would have posted them as links)
A request sends a lot of information to the server. If you console.log the request in NodeJS, you will see that it contains a lot of information that isn't entirely relevant to what you need.
You're using Express as your web framework. In this case, req.body is the information that you are sending to the server from the client. Using req.body will make sure that you're not using the extra information passed in to the server from the client. Req.body is your code that you want. (Note: Req.body isn't natively supported by Express v4, you'll have to use something like body-parser) See Express docs for more details
Now, let's break up this code a bit. You essentially have 3 separate functions. Let's take a look at validatePostStory.
function validatePostStory(data) {
var array = [];
if (!data.name || typeof data.name !== 'String') {
return array.push('name');
}
return array;
}
This function is a validation function. It takes one argument - an object and returns an array. Effectively, what this is doing is checking if the name is a string or not - if not, return an array that has a length of 1. The following conditional checks length and returns a 400 if greater than 0
if(validation.length > 0) {
return res.badRequestError(validation);
}
I'm not entirely sure why this needs to be a separate function. Looks like you can probably just do this instead.
if (!req.body.name || typeof req.body.name !== 'String') {
return res.badRequestError(validation);
}
The following function function essentially converts the data so that mongodb/mongoose can store it in the proper format
function parsePostStory(data) {
return {
name : data.name
}
}
It's the same as saying:
var story = {name: req.body.name}
I would assume Story.create is a custom mongoose method yes.

Resources