HTTP 400 on IBM Cloud (Cloud Foundry) with Node.js an Express - ibm-cloud

I have a simple app with two routes, which I use locally and on IBM Cloud/Cloud Foundry (512 M RAM)
/
returns "Hello World!" & 200 locally and on the IBM Cloud
/getData
returns some data locally & 200
on cloud it returns 400, no logs
Edit:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
var cors = require("cors"); // Cors
app.use(cors());
var port = process.env.PORT || 3000;
app.get('/', (req, res) => res.send('Hello World!'))
// *************** GETDATA ***************************************
app.get('/getData', function (req, res) {
var request = require("request");
var httpHeaderOptions = {
accept: "application/json",
"content-type": "application/json",
apikey: req.headers.apikey
};
var restoptions = {
method: "GET",
url: req.headers.route,
headers: httpHeaderOptions
};
// console.log("headers: " + JSON.stringify(req.headers));
// console.log("GET DOCS: \n", JSON.stringify(restoptions));
request(restoptions, function (error, response, body) {
console.log(typeof (body));
body_json = JSON.parse(body);
if (error) {
console.error("Failed: %s", error.message);
body = {
"error": error.message
};
res.status(400).json(body);
} else {
console.log("Success: \n", body);
res.status(200).json(body_json);
}
});
});
// *************** POST DOC ***************************************
app.post('/postData', function (req, res) {
var request = require("request");
var httpHeaderOptions = {
accept: "application/json",
"content-type": "application/json",
apikey: req.headers.apikey
};
var restoptions = {
method: "POST",
url: req.headers.route,
headers: httpHeaderOptions,
body: req.body,
json: true
};
console.log("headers: " + JSON.stringify(req.headers));
console.log("POST DOC: \n", JSON.stringify(restoptions));
request(restoptions, function (error, response, body) {
if (typeof (body) == 'object' && Object.keys(body).length === 0) {
// unknown error, empty resposne
res.status(400).json(body);
} else {
console.log("body: " + JSON.stringify(body));
if (error) {
console.error("Failed: %s", error.message);
body = {
"error": error.message
};
res.status(400).json(body);
} else {
console.log("Success: \n", JSON.stringify(body));
res.status(200).json(body);
}
}
});
});
// *********************
app.post('/watsonAssistant', function (req, res) {
var request = require("request");
var reqURL = "https://hackathon-jps.eu-de.mybluemix.net/watsonAssistant";
console.log("URL: \n", reqURL);
console.log("POST Body: \n", JSON.stringify(req.body));
var httpHeaderOptions = {
accept: "application/json",
"content-type": "application/json",
};
var restoptions = {
method: "POST",
url: reqURL,
headers: httpHeaderOptions,
body: req.body,
json: true
};
console.log("send request \n");
request(restoptions, function (error, response, body) {
console.log("in request \n");
if (error) {
console.error("Failed: %s", error.message);
body = {
"error": error.message
};
res.status(400).json(body);
} else {
console.log("Success: \n", body[0]);
res.status(200).json(body[0]);
}
});
});
// Start the server
app.listen(port, function () {
console.log('simple forward server is running')
});
link to the code

This will be because whatever req.headers.route is set to, is not visible to the app when it is running in the cloud. Your first check should be on error. Your second check should be if body is not null, and an object instead you immediately JSON.parse body, which may be throwing a parsing exception.

Related

Unable to receive mail sent via sendgrid

I'm creating a contact form using Nextjs and SendGrid, according to this header status
202
{
server: 'nginx',
date: 'Thu, 08 Dec 2022 16:29:25 GMT',
'content-length': '0',
connection: 'close',
'x-message-id': 'CaVdpVAURza6JrUF7yIQQA',
'access-control-allow-origin': 'https://sendgrid.api-docs.io',
'access-control-allow-methods': 'POST',
'access-control-allow-headers': 'Authorization, Content-Type, On-behalf-
of, x-sg-elas-acl',
'access-control-max-age': '600',
'x-no-cors-reason':
'https://sendgrid.com/docs/Classroom/Basics/API/cors.html',
'strict-transport-security': 'max-age=600; includeSubDomains'
}
the email is sent but I find nothing in my inbox,
and this error occurs in the terminal
API resolved without sending a response for /api/contact, this may result in stalled requests.
I don't know what mistake I've done but. I invite you to look at my code bellow:
API :
import sgMail from "#sendgrid/mail";
export default function handler(req, res) {
if (req.method !== "POST") {
res.status(405).json({ message: "INVALID_METHOD" });
return;
}
// Variables from the client side
var name = req.body.name;
var email= req.body.email;
var subject= req.body.subject;
var content = req.body.content;
// auto line break message
const message = content
.replace(/\n/g, "<br>")
.replace(/\r/g, "<br>")
.replace(/\t/g, "<br>")
.replace(/<(?!br\s*\/?)[^>]+>/g, "");
// giving the api key API
sgMail.setApiKey(process.env.KEY_SENDGRID);
// Creating message
const sendGridMail = {
to: "arotiana4612#gmail.com",
from: "kaspersky2mahanaima#gmail.com",
subject: subject,
templateId: "d-b48909edf062437e8442f861a4c8be29",
dynamic_template_data: {
name: name,
email: email,
subject: subject,
content: message,
},
};
// SENDING MESSAGE VIA SENDGRID
(async () => {
try {
await sgMail.send(sendGridMail)
.then((response) => {
console.log(response[0].statusCode)
console.log(response[0].headers)
})
.catch((error) => {
console.error(error)
})
} catch (err){
console.error(err);
res.status(500).json({
error:JSON.stringify(err),
message: "ERROR_WITH_SENDGRID",
});
}
})();
}
And this is the method from the client side that from which I get the data:
const onSubmit: SubmitHandler<Inputs> = async (formData) => {
if (!isLoading) {
setIsLoading(true);
const response = await fetch("/api/contact", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(formData),
});
const result = await response.json();
setIsLoading(false);
if (!response.ok) {
console.log("error sending email:",result);
} else {
console.log("ok");
}
return result;
}
};
I want to receive the mail in my inbox. Your help would be very appreciated, I'm strugling

Sharepoint list item using Api Rest

I need to get a list's items, so I created this function
export function retrieveSPItems(spToken, alias) {
var url = `{path_to_my_site}/_api/web/Lists/getByTitle('Briefs')/ItemCount`;
var myHeaders = new Headers({
Accept: "application/json;odata=nometadata",
Authorization: spToken,
});
return fetch(url, {
method: "get",
headers: myHeaders,
}).then((response) => response.json());
}
As a output I get 3000.
when I change the url to
var url = `{path_to_my_site}/_api/web/Lists/getByTitle('Briefs')/Items`;
I get an empty list!
PS :
It's work in Postman with no problem
The token is generated by adaljs :
Get Token
authContext.acquireToken(SP_BASE_URL, function (error, token){....})
Adal config
export const adalConfig = {
tenant: CURRENT_TENANT,
clientId: CURRENT_APP_ID,
endpoints: {
api: CURRENT_APP_ID,
graph: GRAPH_BASE_URL,
sharepoint: SP_BASE_URL,
},
cacheLocation: "localStorage",
validateAuthority: true,
};
So I need to know :
what the reason fot this issue?
How can I fix it?
It's too general information, you need debug and figure out the detailed error information.
My test demo:
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="Scripts/adal.js"></script>
<script type="text/javascript">
var authContext = null;
var user = null;
(function () {
window.config = {
instance: 'https://login.microsoftonline.com/',
tenant: 'xxx.onmicrosoft.com',
clientId: '9afc37cb-x-x-x-xxx',
postLogoutRedirectUri: window.location.origin,
endpoints: {
graphApiUri: "https://graph.microsoft.com",
sharePointUri: "https://xxx.sharepoint.com/",
},
cacheLocation: 'localStorage' // enable this for IE, as sessionStorage does not work for localhost.
};
authContext = new AuthenticationContext(config);
var isCallback = authContext.isCallback(window.location.hash);
authContext.handleWindowCallback();
//$errorMessage.html(authContext.getLoginError());
if (isCallback && !authContext.getLoginError()) {
window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST);
}
user = authContext.getCachedUser();
if (!user) {
authContext.login();
}
//authContext.acquireToken(window.config.clientId, function (error, token) {
// console.log('---');
//})
authContext.acquireToken(window.config.endpoints.sharePointUri, function (error, token) {
alert(token);
if (error || !token) {
console.log("ADAL error occurred: " + error);
return;
}
else {
var listUri = window.config.endpoints.sharePointUri + "sites/lee/_api/web/lists/GetByTitle('mylist')/items?$select=Title";
$.ajax({
type: "GET",
url: listUri,
headers: {
"Authorization": "Bearer " + token,
"accept": "application/json;odata=verbose"
}
}).done(function (response) {
console.log("Successfully fetched list from SharePoint.");
var items = response.d.results;
for (var i = 0; i < items.length; i++) {
console.log(items[i].Title);
$("#SharePoint").append("<li>" + items[i].Title + "</li>");
}
}).fail(function () {
console.log("Fetching list from SharePoint failed.");
})
}
})
}());
</script>

How to call http.post using protractor in typescript

I am trying to do http post in protractor. The status of http.post sits in pending status and doesn't return any response.
I am calling a method in onPrepare function under specDone:
jasmine.getEnv().addReporter({
specDone: function(result) {
if (result.status == "failed") {
browser.getCapabilities().then(function(caps) {
var browserName = caps.get("browserName");
browser.takeScreenshot().then(function(png) {
var stream = fs.createWriteStream(
"./reports/screenshots/" +
browserName +
"-" +
result.fullName +
".png"
);
stream.write(new Buffer(png, "base64"));
stream.end();
});
});
}
new PortalData().PushDataToPortal("");
}
});
Below function in called from onPrepare, the API takes the parameter from body. I am using protractor-http-client package for API calls.
export class PortalData {
public PushDataToPortal(result) {
const http: HttpClient = new HttpClient();
const LogFilePathInSharedLocation =
"\\\\10.101.101.11\\temp\\DocStar\\Automation\\TestLogs\\Logs.txt";
http
.post(
someurl,
LogFilePathInSharedLocation,
{ "Content-Type": "application/x-www-form-urlencoded" }
)
.then((response: ResponsePromise) => {
console.log(response);
});
}
Please advise. Thanks!
I would suggest you use Http call in beforeAll instead of onPrepare.
You can try superagent or supertest npm modules:
Example for superagent
const superagent = require('superagent');
// callback
superagent
.post('/api/pet')
.send({ name: 'Manny', species: 'cat' }) // sends a JSON post body
.set('X-API-Key', 'foobar')
.set('accept', 'json')
.end((err, res) => {
// Calling the end function will send the request
});
// promise with then/catch
superagent.post('/api/pet').then(console.log).catch(console.error);
// promise with async/await
(async () => {
try {
const res = await superagent.post('/api/pet');
console.log(res);
} catch (err) {
console.error(err);
}
})();
Example for supertest
const supertest = require('supertest');
const request = supertest(`${baseURL}`);
request.put('/test/sendlocal')
.send(profileAddressData.createData)
.set('Content-Type', 'application/json')
.set('Accept', '*/*')
.expect(200)
.end((err, res) => {
if (err) {
console.error('Error: ', err);
console.error('Response: ', res);
}
});

Angular 2 Http Post with Promise failing, not sending data

I am attempting to make a http.post call with angular 2. I have tested the call in postman, so I know that the api is working. I get an error, input empty which means that it isn't getting the data. I've read a few answers and articles, but not able to make a successful call with the data.
Can anyone give me some insight into what I am missing?
public upload(name: string, data: any, result, contentType: string) : Promise<Response> {
let headers = new Headers({ 'Content-Type': contentType });
let options = new RequestOptions({ headers: headers });
return this.http
.post(this.urlAPI, data, options)
.toPromise()
.then(this.extractData)
.catch(this.handleError);
}
extractData(res:Response) {
console.log('res: ', res);
let body = res.json();
return Promise.resolve(res);
}
handleError(err: any): Promise<any> {
console.error('An Error has occured: ', err);
return Promise.reject(err);
}
I am not sure what is the type of your 'data'. Data has to be stringified before sent. Below is a workable version for me.
saveNote(note: ApprovalNoteModel): Observable<ApprovalNoteModel> {
let body = JSON.stringify(note);
let headers = this.utilsSvc.getAuthHeaders();
headers.set('Content-Type', 'application/json');
return this.http.post('cloud/api/approval/note', body,
{ headers: headers }
).map(response => response.json());
}
If it is a file, then you can not do that thru 'http', I believe. Here is my workable version.
addFileRequest(referenceId: number, licenseId: number, url: string, files: File[]): Observable<any> {
return Observable.create(observer => {
this.progressObserver = observer;
let formData: FormData = new FormData(),
xhr: XMLHttpRequest = new XMLHttpRequest();
formData.append('referenceId', referenceId);
formData.append('licenseId', licenseId);
for (let i = 0; i < files.length; i++) {
formData.append("uploads[]", files[i], files[i].name);
}
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
observer.next(xhr.response);
observer.complete();
} else {
if (xhr.response.status)
observer.error(xhr.response);
else
observer.error({ 'status': xhr.status, '_body': xhr.response });
}
}
};
xhr.upload.onprogress = (event) => {
this.progress = Math.round(event.loaded / event.total * 100);
this.progressObserver.next(this.progress);
};
xhr.open('POST', url, true);
xhr.setRequestHeader('Authorization', this.utilsSvc.getToken());
xhr.send(formData);
});
}

How to post to facebook serverside with Node.js

As per the question title, I am trying to post to facebook serverside with node.js
Unfortunately there is something wrong with how I am doing it...
I am getting the error
{ [Error: socket hang up] code: 'ECONNRESET' }
app.post('/post/:id?', function(req, res)
{
var id = req.route.params.id;
var token = tokens[id].token;
var path = '/' + id + '/feed?access_token=' + token;
var message = "server side post to facebook";
console.log("post.id = " + req.route.params.id);
var jsonobject = JSON.stringify(
{
'message' : message
});
var options = {
host: 'graph.facebook.com',
port: 443,
path: path,
method: 'post',
headers: {
'content-type': 'application/json',
'content-length': jsonobject.length()
}
};
var req = https.request(options, function(res) {
console.log("statuscode: ", res.statuscode);
console.log("headers: ", res.headers);
res.setencoding('utf8');
res.on('data', function(d) {
process.stdout.write(d);
});
res.on('end', function(){ // see http nodejs documentation to see end
console.log("finished posting message");
});
});
req.on('error', function(e) {
console.error(e);
});
req.write(jsonobject);
req.end();
});
I am not sure exactly what I did, but after lots of hacking it seems to work...
So for anyone who is interested:
app.post('/post/:id?', function(req, res)
{
var id = req.route.params.id;
var token = tokens[id].token;
var path = '/' + id + '/feed?access_token=' + token;
var strToPost = "server side post to facebook";
console.log("post.id = " + req.route.params.id);
var post_data = querystring.stringify({
'message' : 'testing server side post'
});
var options = {
host: 'graph.facebook.com',
port: 443,
path: path,
method: 'POST',
headers: {
'Content-Type' : 'application/x-www-form-urlencoded',
'Content-Length' : post_data.length
}
};
var req = https.request(options, function(res) {
console.log("statuscode: ", res.statuscode);
console.log("headers: ", res.headers);
res.setEncoding('utf8');
res.on('data', function(d) {
console.log("res.on data");
process.stdout.write(d);
});
res.on('end', function(){ // see http nodejs documentation to see end
console.log("\nfinished posting message");
});
});
req.on('error', function(e) {
console.log("\nProblem with facebook post request");
console.error(e);
});
req.write(post_data);
req.end();
});