Mautic API cannot create DynamicContent - node.js

I am struggling to successfully execute create calls on the mautic REST api. In my node project I am using a standard express installation and a wrapper for the node api https://github.com/sambarnes90/node-mautic
I have authenticated my machine with the api and can PULL data without problem. The problem is POSTing data to it.
The documentation for the targeted post request is here: https://developer.mautic.org/#create-dynamic-content
This is my route. It derives from the example in node-mautic which works fine, but putting something into mautic does not work for me:
router.get('/api', function(req, res, next) {
//check auth and create config object
mautic.auth.checkAuth(function(config) {
// if all worked
if (config.auth_object) {
var testbody = {
"name": "apitest2"
}
//create call
mautic.dynamiccontent.createDynamicContent(config, testbody, function(data) {
console.log(data);
return res.send(data);
});
//request call for id=3
/*mautic.dynamiccontent.getDynamicContent(config, 3, function(data) {
console.log(data);
return res.send(data);
});
});*/
}
});
});
I am getting this response from the API:
[ { code: 400,
message: 'name: A name is required.',
details: { name: [Array] } } ]
This is the GitHub project for this: https://github.com/raphaelurban/mautic-api-test
EDIT:
I also tried:
var testbody = new Array();
testbody['name'] = 'apitest2';
with the same result.
Here is the full POST request:
Request {
domain: null,
_events:
{ error: [Function: bound ],
complete: [Function: bound ],
pipe: [Function] },
_eventsCount: 3,
_maxListeners: undefined,
body: '{"name":"apitest2"}',
callback: [Function],
method: 'POST',
readable: true,
writable: true,
explicitMethod: true,
_qs:
Querystring {
request: [Circular],
lib: { formats: [Object], parse: [Function], stringify: [Function] },
useQuerystring: undefined,
parseOptions: {},
stringifyOptions: {} },
_auth:
Auth {
request: [Circular],
hasAuth: false,
sentAuth: false,
bearerToken: null,
user: null,
pass: null },
_oauth: OAuth { request: [Circular], params: null },
_multipart:
Multipart {
request: [Circular],
boundary: 'afa47f83-3327-4d67-982d-4db6daab8a39',
chunked: false,
body: null },
_redirect:
Redirect {
request: [Circular],
followRedirect: true,
followRedirects: true,
followAllRedirects: false,
followOriginalHttpMethod: false,
allowRedirect: [Function],
maxRedirects: 10,
redirects: [],
redirectsFollowed: 0,
removeRefererHeader: false },
_tunnel:
Tunnel {
request: [Circular],
proxyHeaderWhiteList:
[ 'accept',
'accept-charset',
'accept-encoding',
'accept-language',
'accept-ranges',
'cache-control',
'content-encoding',
'content-language',
'content-location',
'content-md5',
'content-range',
'content-type',
'connection',
'date',
'expect',
'max-forwards',
'pragma',
'referer',
'te',
'user-agent',
'via' ],
proxyHeaderExclusiveList: [] },
headers: { host: 'hrutest.mautic.net', 'content-length': 19 },
setHeader: [Function],
hasHeader: [Function],
getHeader: [Function],
removeHeader: [Function],
localAddress: undefined,
pool: {},
dests: [],
__isRequestRequest: true,
_callback: [Function],
uri:
Url {
protocol: 'https:',
slashes: true,
auth: null,
host: 'hrutest.mautic.net',
port: 443,
hostname: 'hrutest.mautic.net',
hash: null,
search: '?access_token=ZTJlOWY3MzI0YTg4OWViNzU3YjY5YjFiZjRlOTU1OWFiYWM1N2ZmOTQ4OWI4NGI2NzZjZGUyMDg3ZWMxZmU5OA',
query: 'access_token=ZTJlOWY3MzI0YTg4OWViNzU3YjY5YjFiZjRlOTU1OWFiYWM1N2ZmOTQ4OWI4NGI2NzZjZGUyMDg3ZWMxZmU5OA',
pathname: '/api/dynamiccontents/new',
path: '/api/dynamiccontents/new?access_token=ZTJlOWY3MzI0YTg4OWViNzU3YjY5YjFiZjRlOTU1OWFiYWM1N2ZmOTQ4OWI4NGI2NzZjZGUyMDg3ZWMxZmU5OA',
href: 'https://hrutest.mautic.net/api/dynamiccontents/new?access_token=ZTJlOWY3MzI0YTg4OWViNzU3YjY5YjFiZjRlOTU1OWFiYWM1N2ZmOTQ4OWI4NGI2NzZjZGUyMDg3ZWMxZmU5OA' },
proxy: null,
tunnel: true,
setHost: true,
originalCookieHeader: undefined,
_disableCookies: true,
_jar: undefined,
port: 443,
host: 'hrutest.mautic.net',
path: '/api/dynamiccontents/new?access_token=ZTJlOWY3MzI0YTg4OWViNzU3YjY5YjFiZjRlOTU1OWFiYWM1N2ZmOTQ4OWI4NGI2NzZjZGUyMDg3ZWMxZmU5OA',
httpModule:
{ Server: { [Function: Server] super_: [Object] },
createServer: [Function: createServer],
globalAgent:
Agent {
domain: null,
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object],
requests: {},
sockets: [Object],
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: [Object] },
Agent: { [Function: Agent] super_: [Object] },
request: [Function: request],
get: [Function: get] },
agentClass:
{ [Function: Agent]
super_: { [Function: Agent] super_: [Object], defaultMaxSockets: Infinity } },
agent:
Agent {
domain: null,
_events: { free: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: { path: null },
requests: {},
sockets: { 'hrutest.mautic.net:443:::::::::': [Array] },
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: { map: [Object], list: [Array] } } }

I haven't had much chance to test any more of this wrapper in recent months.
I would try sending it as an array though if possible?
Try these two combinations of testbody:
var testbody = [
"name": "apitest2"
]
Or
var testbody = {[
"name": "apitest2"
]}
And see what results you get?
Can you possibly get full logs of the request?

Finally I worked it out. At least it is some solution, I am not sure if this also works with the current function.
I found that all other tutorials use form instead of body when posting data. Additionally, their objects do not get JSON.stringified.
So with my object:
var testbody = {
name: 'apitest99'
};
It works when I change the function in node-mautic:
createDynamicContent: function(config, queryParameters, callback) {
var url = config.api_endpoint + "/dynamiccontents/new?access_token=" + config.auth_object.access_token;
//queryParameters = JSON.stringify(queryParameters);**
request.post({
url: url,
form: queryParameters
}, function(err, res) {
if (err) {
callback(err);
} else {
var asset = JSON.parse(res.body);
callback(asset);
}
})
},
And I am getting the following response from the API:
{ dynamicContent:
{ isPublished: true,
dateAdded: '2018-07-13T09:37:07+00:00',
dateModified: null,
createdBy: 1,
createdByUser: 'Raphael',
modifiedBy: null,
modifiedByUser: null,
id: 10,
name: 'apitest99',
category: null,
publishUp: null,
publishDown: null,
sentCount: 0,
variantParent: null,
variantChildren: [],
content: null,
filters: [],
isCampaignBased: true,
slotName: '' } }

Related

How to get a token for Rest Client?

When I authorize, it passes without errors, but I can’t get a token for further requests (get, post).
As a result, I should get such a token:
{
"token": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJyb2xlX25hbWUiOiLQkNC00LzQuNC90LjRgdGC0YDQsNGC0L7RgCIsImlhdCI6MTU4NTI5MDY5MSwiZXhwIjoxNTg1Mjk0MjkxfQ.saODDtA27NAf6hThUhvltfv6bpeieWDQ8bYxLhjq6Dc"
}
But I do not see him in the object.
Result:
Request {
maxAttempts: 4,
retryDelay: 5000,
fullResponse: true,
attempts: 1,
options: {
url: 'http://localhost:3000/api/auth/login',
method: 'POST',
json: { username: 'admin', password: '123456' },
maxAttempts: 5,
retryDelay: 5000,
fullResponse: true,
promiseFactory: [Function: defaultPromiseFactory]
},
retryStrategy: [Function: HTTPError],
delayStrategy: [Function],
_timeout: null,
_req: Request {
_events: [Object: null prototype] {
error: [Function: bound ],
complete: [Function: bound ],
pipe: [Function]
},
_eventsCount: 3,
_maxListeners: undefined,
method: 'POST',
maxAttempts: 5,
retryDelay: 5000,
fullResponse: true,
promiseFactory: [Function: defaultPromiseFactory],
callback: [Function],
readable: true,
writable: true,
explicitMethod: true,
_qs: Querystring {
request: [Circular],
lib: [Object],
useQuerystring: undefined,
parseOptions: {},
stringifyOptions: {}
},
_auth: Auth {
request: [Circular],
hasAuth: false,
sentAuth: false,
bearerToken: null,
user: null,
pass: null
},
_oauth: OAuth { request: [Circular], params: null },
_multipart: Multipart {
request: [Circular],
boundary: 'd1a5b314-42ec-44c0-87ab-c4ebf0a28613',
chunked: false,
body: null
},
_redirect: Redirect {
request: [Circular],
followRedirect: true,
followRedirects: true,
followAllRedirects: false,
followOriginalHttpMethod: false,
allowRedirect: [Function],
maxRedirects: 10,
redirects: [],
redirectsFollowed: 0,
removeRefererHeader: false
},
_tunnel: Tunnel {
request: [Circular],
proxyHeaderWhiteList: [Array],
proxyHeaderExclusiveList: []
},
headers: {
host: 'localhost:3000',
accept: 'application/json',
'content-type': 'application/json',
'content-length': 40
},
setHeader: [Function],
hasHeader: [Function],
getHeader: [Function],
removeHeader: [Function],
localAddress: undefined,
pool: {},
dests: [],
__isRequestRequest: true,
_callback: [Function: bound ] AsyncFunction,
uri: Url {
protocol: 'http:',
slashes: true,
auth: null,
host: 'localhost:3000',
port: '3000',
hostname: 'localhost',
hash: null,
search: null,
query: null,
pathname: '/api/auth/login',
path: '/api/auth/login',
href: 'http://localhost:3000/api/auth/login'
},
proxy: null,
tunnel: false,
setHost: true,
originalCookieHeader: undefined,
_disableCookies: true,
_jar: undefined,
port: '3000',
host: 'localhost',
path: '/api/auth/login',
_json: true,
body: '{"username":"admin","password":"123456"}',
httpModule: {
_connectionListener: [Function: connectionListener],
METHODS: [Array],
STATUS_CODES: [Object],
Agent: [Function],
ClientRequest: [Function: ClientRequest],
IncomingMessage: [Function: IncomingMessage],
OutgoingMessage: [Function: OutgoingMessage],
Server: [Function: Server],
ServerResponse: [Function: ServerResponse],
createServer: [Function: createServer],
get: [Function: get],
request: [Function: request],
maxHeaderSize: [Getter],
globalAgent: [Getter/Setter]
},
agentClass: [Function: Agent] { defaultMaxSockets: Infinity },
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 80,
protocol: 'http:',
options: [Object],
requests: {},
sockets: {},
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256
}
},
_callback: null,
_resolve: [Function: promiseResolve],
_reject: [Function: promiseReject],
_promise: Promise {
_handler: Pending {
consumers: undefined,
receiver: undefined,
handler: undefined,
resolved: false
}
},
reply: [Function: requestRetryReply]
}
request:
const auth = {
username : "admin",
password : "123456"
}
var options = {
url: `${config.url}/api/auth/login`,
method: 'POST',
json: auth
};
try {
var result = request(options);
console.log(result)
} catch {
console.log('[ERROR]:', err);
}
Didn't you forget the callback? I mean:
const auth = {
username : "admin",
password : "123456"
}
var options = {
url: `${config.url}/api/auth/login`,
method: 'POST',
json: auth
};
request(options, function(err, res, body) {
if(err){
console.log('[ERROR]:', err);
}
else{
let result = JSON.parse(body);
console.log(result);
}
});
...

Async Await style call working for nano.db.insert but not for nano.db.list

I am using https://github.com/apache/couchdb-nano to interact with my couchdb instance, in my nodeJS project.
const nano = = require('nano')('http://127.0.0.1:5984');
const eventsDb = nano.db.use('events');
const savedEvent = await eventsDb.insert({title: 'ABC'});
console.log('savedEvent:');
console.log(savedEvent.body);
The above works but the following does not (i-e it logs undefined):
const databases = await nano.db.list();
console.log(databases.body);
console.log(databases.rows);
and the following prints a long trace:
const databases = await nano.db.list();
console.log(databases);
The last one above prints the following:
Request {
_events: [Object: null prototype] { pipe: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
method: 'GET',
headers:
{ 'content-type': 'application/json',
accept: 'application/json',
host: '127.0.0.1:5984' },
uri:
Url {
protocol: 'http:',
slashes: true,
auth: null,
host: '127.0.0.1:5984',
port: '5984',
hostname: '127.0.0.1',
hash: null,
search: null,
query: null,
pathname: '/_all_dbs',
path: '/_all_dbs',
href: 'http://127.0.0.1:5984/_all_dbs' },
readable: true,
writable: true,
explicitMethod: true,
_qs:
Querystring {
request: [Circular],
lib:
{ formats: [Object], parse: [Function], stringify: [Function] },
useQuerystring: undefined,
parseOptions: {},
stringifyOptions: {} },
_auth:
Auth {
request: [Circular],
hasAuth: false,
sentAuth: false,
bearerToken: null,
user: null,
pass: null },
_oauth: OAuth { request: [Circular], params: null },
_multipart:
Multipart {
request: [Circular],
boundary: '85e773c9-18a7-4dee-8564-776339438318',
chunked: false,
body: null },
_redirect:
Redirect {
request: [Circular],
followRedirect: true,
followRedirects: true,
followAllRedirects: false,
followOriginalHttpMethod: false,
allowRedirect: [Function],
maxRedirects: 10,
redirects: [],
redirectsFollowed: 0,
removeRefererHeader: false },
_tunnel:
Tunnel {
request: [Circular],
proxyHeaderWhiteList:
[ 'accept',
'accept-charset',
'accept-encoding',
'accept-language',
'accept-ranges',
'cache-control',
'content-encoding',
'content-language',
'content-location',
'content-md5',
'content-range',
'content-type',
'connection',
'date',
'expect',
'max-forwards',
'pragma',
'referer',
'te',
'user-agent',
'via' ],
proxyHeaderExclusiveList: [] },
setHeader: [Function],
hasHeader: [Function],
getHeader: [Function],
removeHeader: [Function],
localAddress: undefined,
pool: {},
dests: [],
__isRequestRequest: true,
proxy: null,
tunnel: false,
setHost: true,
originalCookieHeader: undefined,
_disableCookies: true,
_jar: false,
port: '5984',
host: '127.0.0.1',
path: '/_all_dbs',
httpModule:
{ _connectionListener: [Function: connectionListener],
METHODS:
[ 'ACL',
'BIND',
'CHECKOUT',
'CONNECT',
'COPY',
'DELETE',
'GET',
'HEAD',
'LINK',
'LOCK',
'M-SEARCH',
'MERGE',
'MKACTIVITY',
'MKCALENDAR',
'MKCOL',
'MOVE',
'NOTIFY',
'OPTIONS',
'PATCH',
'POST',
'PROPFIND',
'PROPPATCH',
'PURGE',
'PUT',
'REBIND',
'REPORT',
'SEARCH',
'SOURCE',
'SUBSCRIBE',
'TRACE',
'UNBIND',
'UNLINK',
'UNLOCK',
'UNSUBSCRIBE' ],
STATUS_CODES:
{ '100': 'Continue',
'101': 'Switching Protocols',
'102': 'Processing',
'103': 'Early Hints',
'200': 'OK',
'201': 'Created',
'202': 'Accepted',
'203': 'Non-Authoritative Information',
'204': 'No Content',
'205': 'Reset Content',
'206': 'Partial Content',
'207': 'Multi-Status',
'208': 'Already Reported',
'226': 'IM Used',
'300': 'Multiple Choices',
'301': 'Moved Permanently',
'302': 'Found',
'303': 'See Other',
'304': 'Not Modified',
'305': 'Use Proxy',
'307': 'Temporary Redirect',
'308': 'Permanent Redirect',
'400': 'Bad Request',
'401': 'Unauthorized',
'402': 'Payment Required',
'403': 'Forbidden',
'404': 'Not Found',
'405': 'Method Not Allowed',
'406': 'Not Acceptable',
'407': 'Proxy Authentication Required',
'408': 'Request Timeout',
'409': 'Conflict',
'410': 'Gone',
'411': 'Length Required',
'412': 'Precondition Failed',
'413': 'Payload Too Large',
'414': 'URI Too Long',
'415': 'Unsupported Media Type',
'416': 'Range Not Satisfiable',
'417': 'Expectation Failed',
'418': 'I\'m a Teapot',
'421': 'Misdirected Request',
'422': 'Unprocessable Entity',
'423': 'Locked',
'424': 'Failed Dependency',
'425': 'Unordered Collection',
'426': 'Upgrade Required',
'428': 'Precondition Required',
'429': 'Too Many Requests',
'431': 'Request Header Fields Too Large',
'451': 'Unavailable For Legal Reasons',
'500': 'Internal Server Error',
'501': 'Not Implemented',
'502': 'Bad Gateway',
'503': 'Service Unavailable',
'504': 'Gateway Timeout',
'505': 'HTTP Version Not Supported',
'506': 'Variant Also Negotiates',
'507': 'Insufficient Storage',
'508': 'Loop Detected',
'509': 'Bandwidth Limit Exceeded',
'510': 'Not Extended',
'511': 'Network Authentication Required' },
Agent:
{ [Function: Agent] super_: [Function], defaultMaxSockets: Infinity },
ClientRequest: { [Function: ClientRequest] super_: [Function] },
globalAgent:
Agent {
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 80,
protocol: 'http:',
options: [Object],
requests: {},
sockets: {},
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256 },
IncomingMessage: { [Function: IncomingMessage] super_: [Function] },
OutgoingMessage: { [Function: OutgoingMessage] super_: [Function] },
Server: { [Function: Server] super_: [Function] },
ServerResponse: { [Function: ServerResponse] super_: [Function] },
createServer: [Function: createServer],
get: [Function: get],
request: [Function: request],
maxHeaderSize: [Getter] },
agentClass:
{ [Function: Agent]
super_:
{ [Function: EventEmitter]
EventEmitter: [Circular],
usingDomains: false,
defaultMaxListeners: [Getter/Setter],
init: [Function],
listenerCount: [Function] },
defaultMaxSockets: Infinity },
agent:
Agent {
_events: [Object: null prototype] { free: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 80,
protocol: 'http:',
options: { path: null },
requests: {},
sockets: {},
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256 } }
Can anyone help ? Do all nano api(s) work in async/await style ?
The last stack trace tells me that you are receiving a Request object back in your databases variable. This was the default behaviour for Nano prior to version 7.0.0.
If you use the latest Nano (v8.0.1 at the time of writing) then most Nano functions return a Promise instead of a Request object - this will make your async/await code work correctly i.e. your variable databases will receive the body of the HTTP request when the Promise resolves.
To ensure you have the latest Nano use npm install nano or modify your project's package.json file to ensure that the version number requested is current before running npm install.
You can't use await in that way because await works only inside async functions. try the following:
async function getDatabases() {
const databases = await nano.db.list();
console.log(databases.body);
console.log(databases.rows);
}
getDatabases();
Check this tutorial about async/await to get more familiar async/await tutorial

NodeJs ECONNRESET

I get an error when I'm executing GET request.
Error: read ECONNRESET
at TLSWrap.onStreamRead (internal/stream_base_commons.js:111:27) errno: 'ECONNRESET', code: 'ECONNRESET', syscall: 'read' }
It happens when I try to make GET request to https://www.adidas.co.uk/api/search/taxonomy?query=men but it works when I use https://jsonplaceholder.typicode.com/api/todos/1.
Request:
var request = require('request');
[...]
app.use('/api', cacheMiddleware(), function (req, out) {
var headers = {
//'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0',
'Content-Type': 'application/x-www-form-urlencoded'
//'Content-Type': 'application/jsond'
};
var url = getDestinationUrl(req);
if (req.method === 'POST') {
console.log('POST body:')
console.log(req.body);
result = request.post({ uri: url, json: req.body, headers: headers, followRedirect: true , maxRedirects: 10}, function (error, response, body) { handleResponse(req, out, error, response, body) });
} else {
result = request({ uri: url, headers: headers, followRedirect: true, maxRedirects: 10 }, function (error, response, body) { handleResponse(req, out, error, response, body) });
}
});
log:
handle https://www.adidas.co.uk/api/search/taxonomy?query=men
REQUEST { uri: 'https://www.adidas.co.uk/api/search/taxonomy?query=men',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
followRedirect: true,
maxRedirects: 10,
callback: [Function] }
HTTP 10384: SERVER socketOnParserExecute 739
REQUEST make request https://www.adidas.co.uk/api/search/taxonomy?query=men
HTTP 10384: call onSocket 0 0
HTTP 10384: createConnection www.adidas.co.uk:443:::::::::::::::: { servername: 'www.adidas.co.uk',
_defaultAgent:
Agent {
_events: [Object: null prototype] { free: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: { path: null },
requests: {},
sockets: { 'www.adidas.co.uk:443::::::::::::::::': [] },
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: { map: {}, list: [] } },
_events:
[Object: null prototype] {
error: [Function: bound ],
complete: [Function: bound ],
pipe: [Function] },
_eventsCount: 3,
_maxListeners: undefined,
uri:
Url {
protocol: 'https:',
slashes: true,
auth: null,
host: 'www.adidas.co.uk',
port: 443,
hostname: 'www.adidas.co.uk',
hash: null,
search: '?query=men',
query: 'query=men',
pathname: '/api/search/taxonomy',
path: '/api/search/taxonomy?query=men',
href: 'https://www.adidas.co.uk/api/search/taxonomy?query=men' },
headers:
{ 'Content-Type': 'application/x-www-form-urlencoded',
host: 'www.adidas.co.uk' },
followRedirect: true,
maxRedirects: 10,
callback: [Function],
readable: true,
writable: true,
_qs:
Querystring {
request:
Request {
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
uri: [Url],
headers: [Object],
followRedirect: true,
maxRedirects: 10,
callback: [Function],
readable: true,
writable: true,
_qs: [Circular],
_auth: [Auth],
_oauth: [OAuth],
_multipart: [Multipart],
_redirect: [Redirect],
_tunnel: [Tunnel],
setHeader: [Function],
hasHeader: [Function],
getHeader: [Function],
removeHeader: [Function],
method: 'GET',
localAddress: undefined,
pool: {},
dests: [],
__isRequestRequest: true,
_callback: [Function],
proxy: null,
tunnel: true,
setHost: true,
originalCookieHeader: undefined,
_disableCookies: true,
_jar: undefined,
port: 443,
host: 'www.adidas.co.uk',
path: '/api/search/taxonomy?query=men',
httpModule: [Object],
agentClass: [Function],
agent: [Agent],
_started: true,
href: 'https://www.adidas.co.uk/api/search/taxonomy?query=men' },
lib:
{ formats: [Object], parse: [Function], stringify: [Function] },
useQuerystring: undefined,
parseOptions: {},
stringifyOptions: {} },
_auth:
Auth {
request:
Request {
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
uri: [Url],
headers: [Object],
followRedirect: true,
maxRedirects: 10,
callback: [Function],
readable: true,
writable: true,
_qs: [Querystring],
_auth: [Circular],
_oauth: [OAuth],
_multipart: [Multipart],
_redirect: [Redirect],
_tunnel: [Tunnel],
setHeader: [Function],
hasHeader: [Function],
getHeader: [Function],
removeHeader: [Function],
method: 'GET',
localAddress: undefined,
pool: {},
dests: [],
__isRequestRequest: true,
_callback: [Function],
proxy: null,
tunnel: true,
setHost: true,
originalCookieHeader: undefined,
_disableCookies: true,
_jar: undefined,
port: 443,
host: 'www.adidas.co.uk',
path: '/api/search/taxonomy?query=men',
httpModule: [Object],
agentClass: [Function],
agent: [Agent],
_started: true,
href: 'https://www.adidas.co.uk/api/search/taxonomy?query=men' },
hasAuth: false,
sentAuth: false,
bearerToken: null,
user: null,
pass: null },
_oauth:
OAuth {
request:
Request {
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
uri: [Url],
headers: [Object],
followRedirect: true,
maxRedirects: 10,
callback: [Function],
readable: true,
writable: true,
_qs: [Querystring],
_auth: [Auth],
_oauth: [Circular],
_multipart: [Multipart],
_redirect: [Redirect],
_tunnel: [Tunnel],
setHeader: [Function],
hasHeader: [Function],
getHeader: [Function],
removeHeader: [Function],
method: 'GET',
localAddress: undefined,
pool: {},
dests: [],
__isRequestRequest: true,
_callback: [Function],
proxy: null,
tunnel: true,
setHost: true,
originalCookieHeader: undefined,
_disableCookies: true,
_jar: undefined,
port: 443,
host: 'www.adidas.co.uk',
path: '/api/search/taxonomy?query=men',
httpModule: [Object],
agentClass: [Function],
agent: [Agent],
_started: true,
href: 'https://www.adidas.co.uk/api/search/taxonomy?query=men' },
params: null },
_multipart:
Multipart {
request:
Request {
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
uri: [Url],
headers: [Object],
followRedirect: true,
maxRedirects: 10,
callback: [Function],
readable: true,
writable: true,
_qs: [Querystring],
_auth: [Auth],
_oauth: [OAuth],
_multipart: [Circular],
_redirect: [Redirect],
_tunnel: [Tunnel],
setHeader: [Function],
hasHeader: [Function],
getHeader: [Function],
removeHeader: [Function],
method: 'GET',
localAddress: undefined,
pool: {},
dests: [],
__isRequestRequest: true,
_callback: [Function],
proxy: null,
tunnel: true,
setHost: true,
originalCookieHeader: undefined,
_disableCookies: true,
_jar: undefined,
port: 443,
host: 'www.adidas.co.uk',
path: '/api/search/taxonomy?query=men',
httpModule: [Object],
agentClass: [Function],
agent: [Agent],
_started: true,
href: 'https://www.adidas.co.uk/api/search/taxonomy?query=men' },
boundary: '54c4df7c-a16d-45e6-a57b-bb7f83e6b1fa',
chunked: false,
body: null },
_redirect:
Redirect {
request:
Request {
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
uri: [Url],
headers: [Object],
followRedirect: true,
maxRedirects: 10,
callback: [Function],
readable: true,
writable: true,
_qs: [Querystring],
_auth: [Auth],
_oauth: [OAuth],
_multipart: [Multipart],
_redirect: [Circular],
_tunnel: [Tunnel],
setHeader: [Function],
hasHeader: [Function],
getHeader: [Function],
removeHeader: [Function],
method: 'GET',
localAddress: undefined,
pool: {},
dests: [],
__isRequestRequest: true,
_callback: [Function],
proxy: null,
tunnel: true,
setHost: true,
originalCookieHeader: undefined,
_disableCookies: true,
_jar: undefined,
port: 443,
host: 'www.adidas.co.uk',
path: '/api/search/taxonomy?query=men',
httpModule: [Object],
agentClass: [Function],
agent: [Agent],
_started: true,
href: 'https://www.adidas.co.uk/api/search/taxonomy?query=men' },
followRedirect: true,
followRedirects: true,
followAllRedirects: false,
followOriginalHttpMethod: false,
allowRedirect: [Function],
maxRedirects: 10,
redirects: [],
redirectsFollowed: 0,
removeRefererHeader: false },
_tunnel:
Tunnel {
request:
Request {
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
uri: [Url],
headers: [Object],
followRedirect: true,
maxRedirects: 10,
callback: [Function],
readable: true,
writable: true,
_qs: [Querystring],
_auth: [Auth],
_oauth: [OAuth],
_multipart: [Multipart],
_redirect: [Redirect],
_tunnel: [Circular],
setHeader: [Function],
hasHeader: [Function],
getHeader: [Function],
removeHeader: [Function],
method: 'GET',
localAddress: undefined,
pool: {},
dests: [],
__isRequestRequest: true,
_callback: [Function],
proxy: null,
tunnel: true,
setHost: true,
originalCookieHeader: undefined,
_disableCookies: true,
_jar: undefined,
port: 443,
host: 'www.adidas.co.uk',
path: '/api/search/taxonomy?query=men',
httpModule: [Object],
agentClass: [Function],
agent: [Agent],
_started: true,
href: 'https://www.adidas.co.uk/api/search/taxonomy?query=men' },
proxyHeaderWhiteList:
[ 'accept',
'accept-charset',
'accept-encoding',
'accept-language',
'accept-ranges',
'cache-control',
'content-encoding',
'content-language',
'content-location',
'content-md5',
'content-range',
'content-type',
'connection',
'date',
'expect',
'max-forwards',
'pragma',
'referer',
'te',
'user-agent',
'via' ],
proxyHeaderExclusiveList: [] },
setHeader: [Function],
hasHeader: [Function],
getHeader: [Function],
removeHeader: [Function],
method: 'GET',
localAddress: undefined,
pool: {},
dests: [],
__isRequestRequest: true,
_callback: [Function],
proxy: null,
tunnel: true,
setHost: true,
originalCookieHeader: undefined,
_disableCookies: true,
_jar: undefined,
port: 443,
host: 'www.adidas.co.uk',
path: null,
httpModule:
{ Agent: { [Function: Agent] super_: [Function] },
globalAgent:
Agent {
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object],
requests: {},
sockets: [Object],
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: [Object] },
Server: { [Function: Server] super_: [Function] },
createServer: [Function: createServer],
get: [Function: get],
request: [Function: request] },
agentClass:
{ [Function: Agent]
super_:
{ [Function: Agent] super_: [Function], defaultMaxSockets: Infinity } },
agent:
Agent {
_events: [Object: null prototype] { free: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: { path: null },
requests: {},
sockets: { 'www.adidas.co.uk:443::::::::::::::::': [] },
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: { map: {}, list: [] } },
_started: true,
href: 'https://www.adidas.co.uk/api/search/taxonomy?query=men',
_agentKey: 'www.adidas.co.uk:443::::::::::::::::' }
HTTP 10384: sockets www.adidas.co.uk:443:::::::::::::::: 1
HTTP 10384: outgoing message end.
HTTP 10384: SOCKET ERROR: read ECONNRESET Error: read ECONNRESET
at TLSWrap.onStreamRead (internal/stream_base_commons.js:111:27)
handleResponse...
Response error
{ Error: read ECONNRESET
at TLSWrap.onStreamRead (internal/stream_base_commons.js:111:27) errno: 'ECONNRESET', code: 'ECONNRESET', syscall: 'read' }
HTTP 10384: outgoing message end.
HTTP 10384: CLIENT socket onClose
HTTP 10384: removeSocket www.adidas.co.uk:443:::::::::::::::: writable: false
HTTP 10384: HTTP socket close
HTTP 10384: server socket close
UPDATE:
It works with axios:
app.use('/api', cacheMiddleware(), function (req, out) {
var url = getDestinationUrl(req);
if (req.method === 'POST') {
axios.post(url, req.body)
.then(response => {
handleResponse(req, out, response, response.data)
})
.catch(error => {
handleResponseError(req, out, error)
});
} else {
axios.get(url)
.then(response => {
handleResponse(req, out, response, response.data)
})
.catch(error => {
handleResponseError(req, out, error)
});
}
});
"ECONNRESET" means the other side of the TCP conversation abruptly
closed its end of the connection.
This error simply means that the other side closed the connection in a way that was probably not normal (or may be in a hurry).
An example is: a socket connection can be closed by the other party abruptly due to several reasons or you lost your wifi signal while running your app. Then you will see this error / exception on your side.
Solution- It happening because you are not listening/handling to the 'error' event, to deal with it you should put a listener which can handle such errors.
Safely "throwing" errors
Safely "catching" errors
Its working in Axios because you are using promises for async error handling.
Besides the above correct answers, this might help somebody.
I experienced the same error message. In my case the env variable for the server I had 'https://servername' instead of 'servername'. Removing the 'https://' piece fix the error.

How to connect to moto standalone server?

I just installed moto and tried to connect to the standalone server with the following node.js code:
const AWS = require('aws-sdk')
const ep = new AWS.Endpoint('http://127.0.0.1:5000')
const route53 = new AWS.Route53({endpoint: ep})
const params = {}
console.log(route53.listHostedZones(params))
The code sets AWS service's endpoint, which points to the standalone server of moto. And then sends listHostedZones request to the endpoint. The output of this program is
Request {
domain: null,
service:
Service {
config:
Config {
credentials: [Object],
credentialProvider: [Object],
region: undefined,
logger: null,
apiVersions: {},
apiVersion: null,
endpoint: [Object],
httpOptions: [Object],
maxRetries: undefined,
maxRedirects: 10,
paramValidation: true,
sslEnabled: true,
s3ForcePathStyle: false,
s3BucketEndpoint: false,
s3DisableBodySigning: true,
computeChecksums: true,
convertResponseTypes: true,
correctClockSkew: false,
customUserAgent: null,
dynamoDbCrc32: true,
systemClockOffset: 0,
signatureVersion: null,
signatureCache: true,
retryDelayOptions: {},
useAccelerateEndpoint: false },
endpoint:
Endpoint {
protocol: 'http:',
host: '127.0.0.1:5000',
port: 5000,
hostname: '127.0.0.1',
pathname: '/',
path: '/',
href: 'http://127.0.0.1:5000/',
constructor: [Object] },
_clientId: 1 },
operation: 'listHostedZones',
params: {},
httpRequest:
HttpRequest {
method: 'POST',
path: '/',
headers: { 'User-Agent': 'aws-sdk-nodejs/2.166.0 darwin/v6.2.2' },
body: '',
endpoint:
Endpoint {
protocol: 'http:',
host: '127.0.0.1:5000',
port: 5000,
hostname: '127.0.0.1',
pathname: '/',
path: '/',
href: 'http://127.0.0.1:5000/',
constructor: [Object] },
region: undefined,
_userAgent: 'aws-sdk-nodejs/2.166.0 darwin/v6.2.2' },
startTime: 2017-12-18T13:27:48.148Z,
response:
Response {
request: [Circular],
data: null,
error: null,
retryCount: 0,
redirectCount: 0,
httpResponse:
HttpResponse {
statusCode: undefined,
headers: {},
body: undefined,
streaming: false,
stream: null },
maxRetries: 3,
maxRedirects: 10 },
_asm:
AcceptorStateMachine {
currentState: 'validate',
states:
{ validate: [Object],
build: [Object],
afterBuild: [Object],
sign: [Object],
retry: [Object],
afterRetry: [Object],
send: [Object],
validateResponse: [Object],
extractError: [Object],
extractData: [Object],
restart: [Object],
success: [Object],
error: [Object],
complete: [Object] } },
_haltHandlersOnError: false,
_events:
{ validate:
[ [Object],
[Function: VALIDATE_REGION],
[Function: BUILD_IDEMPOTENCY_TOKENS],
[Function: VALIDATE_PARAMETERS] ],
afterBuild:
[ [Object],
[Function: SET_CONTENT_LENGTH],
[Function: SET_HTTP_HOST] ],
restart: [ [Function: RESTART] ],
sign: [ [Object] ],
validateResponse: [ [Function: VALIDATE_RESPONSE] ],
send: [ [Object] ],
httpHeaders: [ [Function: HTTP_HEADERS] ],
httpData: [ [Function: HTTP_DATA] ],
httpDone: [ [Function: HTTP_DONE] ],
retry:
[ [Function: FINALIZE_ERROR],
[Function: INVALIDATE_CREDENTIALS],
[Function: EXPIRED_SIGNATURE],
[Function: CLOCK_SKEWED],
[Function: REDIRECT],
[Function: RETRY_CHECK] ],
afterRetry: [ [Object] ],
build: [ [Function: buildRequest], [Function: sanitizeUrl] ],
extractData: [ [Function: extractData], [Function: extractRequestId] ],
extractError: [ [Function: extractError], [Function: extractRequestId] ],
httpError: [ [Function: ENOTFOUND_ERROR] ] },
emit: [Function: emit] }
As you can see in the above output, there's an ENOTFOUND_ERROR error in it. And I couldn't find any new connection in the console output of moto.
The way I start moto is moto_server route53:
> moto_server route53
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
What's wrong with my configurations? I think there's something wrong with my node.js code. Do I misinterpret the meaning of endpoint?
const AWS = require('aws-sdk')
const ep = new AWS.Endpoint('http://127.0.0.1:5000')
const initParam = {
endpoint: ep,
region: 'ap-northeast-1'
}
const route53 = new AWS.Route53(initParam)
let params = {
CallerReference: 'unique_string_affh38h98hasd8f76a',
Name: 'www.example.com'
}
route53.createHostedZone(params, (err, data) => {
if (err) {
console.error(`createHostedZone err: ${err}`)
} else {
console.log(`createHostedZone data: ${JSON.stringify(data)}`)
}
})
I forgot to set region parameter. And the way I view the output of listHostedZones() was wrong. After correcting them, the code works correctly.

Why isn't the https.request callback called?

I have some node.js code where I'm trying to get package.info from raw.github.com. I'm doing a HTTPS request, but for some reason it looks like the callback is never called, because 'here' is never outputted.
Does anyone see what's going wrong?
console.log(options)
req = https.request(options, function(res) {
console.log('here')
res.setEncoding('utf8')
// ... more code here
})
console.log(req)
// .. return -> listening and waiting
Output
{ host: 'raw.github.com',
port: 443,
path: '/jasny/bootstrap/2.2.2-j3-wip/package.json',
method: 'GET' }
{ domain: null,
_events:
{ response: { [Function: g] listener: [Function] },
socket: { [Function: g] listener: [Function] } },
_maxListeners: 10,
output: [],
outputEncodings: [],
writable: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
useChunkedEncodingByDefault: false,
sendDate: false,
_hasBody: true,
_trailer: '',
finished: false,
agent:
{ domain: null,
_events: { free: [Function] },
_maxListeners: 10,
options: {},
requests: {},
sockets: { 'raw.github.com:443': [Object] },
maxSockets: 5,
createConnection: [Function: createConnection] },
socketPath: undefined,
method: 'GET',
path: '/jasny/bootstrap/2.2.2-j3-wip/package.json',
_headers: { host: 'raw.github.com' },
_headerNames: { host: 'Host' }
}
For the full code see lib/packageinfo.js. The function is called in index.js
You need to call end() on the request to execute it, like this:
req = https.request(options, function(res) {
console.log('here')
res.setEncoding('utf8')
// ... more code here
});
req.end(); // <= Here

Resources