I'm new to loopback. I'm trying override response body when model record not found.
this is the default response body from explorer:
{
"error": {
"statusCode": 404,
"name": "Error",
"message": "could not find a model with id 666",
"code": "MODEL_NOT_FOUND",
"stack": "..."
}
}
my expected result:
{
"status": 404,
"message": "could not find a model with id 666"
}
https://loopback.io/doc/en/lb3/Defining-middleware.html#middleware-phases
final - Deal with errors and requests for unknown URLs.
app.middleware('final', function(err, req, res, next) {
if (err && err.code === 'MODEL_NOT_FOUND') {
res.statusCode = 404;
res.json({status: 404, message: err.message});
}else {
next();
}
});
Register the with a file in the boot directory, in a file pointed to by middleware.json, or in server.js.
Related
I'm trying to access the Shopify Orders API in a Loopback application. I have the following data source:
"ShopifyRestDataSource": {
"name": "ShopifyRestDataSource",
"connector": "rest",
"operations": [{
"template": {
"method": "GET",
"url": "https://mystore.myshopify.com/admin",
"headers": {
"accepts": "application/json",
"content-type": "application/json"
}
},
"headers": {
"Authorization": "Basic MzdiOD..."
},
"functions": {
"find": []
}
}]
}
And then I attempt a simple call:
var ds = app.dataSources.ShopifyRestDataSource;
ds.find(function(err, response, context) {
if (err) throw err;
if (response.error) {
next('> response error: ' + response.error.stack);
}
console.log(response);
next();
});
I'm getting the following exception message:
Error: {"errors":"[API] Invalid API key or access token (unrecognized login or wrong password)"}
at callback (/order-api/node_modules/loopback-connector-rest/lib/rest-builder.js:529:21)
The Shopify API authenticates by basic HTTP authentication and I'm sure my request works since the same data works with curl. What am I doing wrong?
I couldn't find the "Loopback way" to do this and I couldn't wait, so I just wrote a simple https Node call. I'll paste this in here but I won't accept it as the answer. I'm still hoping someone will provide the right answer.
let response;
const options = {
hostname: 'mystore.myshopify.com',
port: 443,
path: '/admin/orders.json',
method: 'GET',
auth: `${instance.api_key}:${instance.password}`
};
const req = https.request(options, (res) => {
res.setEncoding('utf8');
let body = '';
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
let jsonResponse = JSON.parse(body);
// application logic goes here
response = 'ok';
});
});
req.on('error', (e) => {
response = e.message;
});
req.end();
I'm trying to use the before Remote hook in loopback to check an user token before the call of my remote method, but the thing is that I can only return a javascript Error, like these.
"error": {
"statusCode": 401,
"name": "Error",
"message": ""
}
This is the code that i'm using in the before remote.
Model.beforeRemote('method', function (context, unused, next) {
let token = Model.app.models.Token;
let id = context.args.Id;
let date = moment();
Rx.Observable.fromPromise(token.find({
where: {
and: [
{ id: id, },
{ expiration: { gt: date } }
]
}
})).subscribe((token => {
if (token.length > 0) {
next();
} else {
let err = new Error();
err.status = 401;
delete err.stack;
return next()
}
}))
});
And I need a "custom" response that isn't an error, something like these.
{
"success": false,
"data": {
"service": "self",
"operation": "rest",
"code": "unauthorized"
},
"message": "Invalid token"
}
I tried with the after Remote hook and I can change the response to get something like that, but I want to get a quicker response in the case that the token is invalid.
Is there any way to achieve this with the before hook? or I had to use after hook?
Thanks
You may want to pass the error to the next function:
return next(err)
I'm writing a lambda in node.js that will call an api(post) and gives back the resulting body and the code is as below.
const AWS = require('aws-sdk');
const request = require('request');
exports.handle = function(e, ctx, callback) {
var bodyDetails = {
uri: "myURL",
json: {
"requestChannel": "web1" },
"method": "POST"
};
callback = ctx.done;
var data = e.bodyJson || {};
request(bodyDetails, function(error, response, body) {
if (!error && response.statusCode === 200) {
console.log(JSON.parse(JSON.stringify(body)));
jsonBody = JSON.parse(JSON.stringify(body));
console.log(body + "\t from suvccess") // Print the json response
callback(null, jsonBody); // Return the JSON object back to our API call
} else {
callback(error);
}
});
}
and I'm testing the same in my lambda console. by passing a blank json {} and I get back the correct response.
Now my next plan is to integrate this piece against API Gateway. So I've created an api for this in my apigateway and in that, I've created a resource named home. and in the home, I created a GET method. with the below details.
Integration type: Lambda Function
Use Lambda Proxy integration : checked
Lambda Region: us-east-1
Lambda Function: myWorkingLambdaName
when I tested this using the test option given by apigateway. I get the response as
Request: /home
Status: 502
Latency: 2942 ms
Response Body
{
"message": "Internal server error"
}
when I see my console I see the values of the success block printed, but the status code is 502. This is very confusing, please let me know where am I going wrong and how can I fix this.
Thanks
API Gateway expects the following properties to be returned from your Lambda:
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}
So, instead of callback(null, jsonBody), you should be calling callback like this:
callback(null, {
isBase64Encoded: false,
statusCode: 200,
headers: {
"Access-Control-Allow-Origin" : "*",
},
body: JSON.stringify(jsonBody),
})
I have tried to upload mp4 file to aws s3 bucket using $cordovaFileTransfer plugin.
This is mycode
bucket.getSignedUrl('putObject', {
Key: 'uploads/ghdfdgjfjhs.mp4'
}, function(err, url) {
console.log('The URL is', url);
document.addEventListener('deviceready', function() {
$cordovaFileTransfer.upload(url, $scope.clip, {})
.then(function(result) {
console.log(result);
}, function(err) {
console.log(err);
}, function(progress) {
});
}, false);
});
Signed url is return successfully.
But return following error
ssl=0xaf974000: I/O error during system call, Connection reset by peer
How to solve this error?
I am trying to call registration webservive in sencha.When I call it on browser its seems ok.But i calling with in the app its gives following error.Please any body help me.
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
here is my code
Ext.Viewport.setMasked({xtype:'loadmask',message:'your custom loadmask'});
Ext.data.JsonP.request({
url: 'http://XXX.XXX.com/api/users/?',
params: {
first_name:'mohit',
last_name:'bisht' ,
city:'ramnagar',
state:'UK',
phone:'9073467465',
email:'test#test.com',
password_digest:'123456',
op:'s'
},
success : function(response,opts) {
Ext.Viewport.setMasked(false);
console.log(response.status);
},
failure : function(response,opts) {
Ext.Viewport.setMasked(false);
if (response.timedout) {
Ext.Msg.alert('error', 'Request to server timed out.');
}
else if (response.aborted) {
Ext.Msg.alert('error', 'Request Aborted by server.');
}
else {
Ext.Msg.alert('error', 'Invalid Request to server.');
}
}
});
Are you sure the service supports jsonp? you can try with an ajax request instead:
Ext.Viewport.setMasked({xtype:'loadmask',message:'your custom loadmask'});
Ext.Ajax.request({
useDefaultXhrHeader: false,
cors: true,
url: 'http://XXX.XXX.com/api/users/?',
params: {
first_name:'mohit',
last_name:'bisht' ,
city:'ramnagar',
state:'UK',
phone:'9073467465',
email:'test#test.com',
password_digest:'123456',
op:'s'
},
success : function(response,opts) {
Ext.Viewport.setMasked(false);
console.log(response.status);
},
failure : function(response,opts) {
Ext.Viewport.setMasked(false);
if (response.timedout) Ext.Msg.alert('error', 'Request to server timed out.');
else if (response.aborted) Ext.Msg.alert('error', 'Request Aborted by server.');
else Ext.Msg.alert('error', 'Invalid Request to server.');
}
});
Hope it helps-