How to customize controller's response with specific exits from helper? - javascript

I'm using Sails.js v1.2.2 and organizing my controllers with single file rather than action 2. Also I use helpers in my controllers.
Now when the helper triggers some exit other than success, the controller will automatically response with the specific format like
{
"cause": {
"name": "Exception",
"code": "ParameterError",
"exit": "ParameterError",
"traceRef": {},
"raw": {
"msg": "My custom message"
}
},
"isOperational": true,
"code": "ParameterError",
"exit": "ParameterError",
"traceRef": {},
"raw": {
"msg": "My custom message"
}
}
How can I custom the response data when the helper exits no-success?
I've tried custom exits in helper file, but not working.

U can use sails generator. sails generate response myCustomHandler. Check docs for custom responses.
Then just try catch helper like in example:
try {
await sails.helpers.test()
.intercept({ code: 'test' }, ()=>{ return new Error('err1') })
} catch (e) {
if (e.message === 'err1') {
return res.badRequest('Test Bad request')
} else if (e.code === 'ParameterError') {
return res.serverError('Parameter Error Message in server error')
} else {
return res.myCustomHandler('Test Custom handler')
}
This is an example with intercept u can use to do more custom stuff. Just ignore it if u don't need that. If u use actions2, then return with this statement. return this.res.myCustomHandler('Some error').
In myCustomHandler.js file, u can format error. Check this docs.

Related

React Admin parseResponse doesn't trigger when query returns error

I'm using React Admin and ra-data-graphQl, when I update something in my UserEdit component all works perfect, BUT, when I need to handle the error message from the API, I don't know where catch it.
This is my Update query:
case 'UPDATE': {
const updateParams = { ...params };
return {
query: gql`mutation updateUser($id: ID!, $data: UpdateUser!) {
data: updateUser(id: $id,input:$data) {
${buildFieldsGraphQL(updateFields)}
}
}`,
variables: {
...updateParams,
id: updateParams.data.uuid,
data: {
...updateParams.data,
},
},
parseResponse: (response) => {
console.log('tr response: ', response);
},
};
}
When the API returns an error, it never reach the console.log.
I was searching a list with options here (https://github.com/marmelab/react-admin/tree/master/packages/ra-data-graphql#options) searching something like "parseError", but I did not find nothing similar.
I need to catch the error and show a message in the UserEdit form.
Reading the link that I share in this post, it say this:
but must return an object matching the options of the ApolloClient query method with an additional parseResponse function.
I understand that I should go to the link in the word "query" and check if there is something like "parserError", but the link is broken:
https://www.apollographql.com/docs/react/reference/index.html#ApolloClient.query
Any help?
Ok, its easier. By adding the onFailure function I can handle the error.

How to store chrome identity api response in vuejs component

I'm passing the response from chrome identity api to the tab that will run my vue powered chrome extension. I need to store this information inside my vue instance tu use it inside a component. I've tried to assign the info to a variable using this.username but it will result in undefined in console. What's wrong with the code and what's the best way to accomplish this?
component code
<script>
import { EventBus } from '../../event-bus';
export default {
data () {
return {
socket: null,
isRegistered: false,
isConnected: false,
username: null,
message: '',
}
},
created() {
},
mounted() {
chrome.runtime.onMessage.addListener(
function(request, sender){
console.log(request);
this.username = request.name;
this.isRegistered = true;
});
EventBus.$emit('open-connection')
// the variable is undefined and also the open-connection event are not emitted?
console.log(this.username)
EventBus.$on('connected', (socket) => {
console.log(socket)
this.socket = socket;
this.isConnected = true;
console.log(this.socket.id)
})
},
methods: {
// I was using this method but the function isn't called inside mounted, result in an error :(
connect(){
//if( this.isRegistered === false){
//this.username = this.username;
//this.isRegistered = true;
//EventBus.$emit('open-connection')
//return this.username;
// }
}
// methods here
}
}
</script>
<style scoped>
</style>
The response from identity api (I will omit the fields value for privacy):
{
"id": "100xxxxxx",
"name": "xxx",
"given_name": "xxxx",
"family_name": "xxxx",
"picture": "https://lh4.googleusercontent.com/xxxxx.jpg",
"locale": "xx"
}
NB: the response object is not accessible in this way key.val
EDIT
After some debug I've finally found a solution. The response information retrived by the api isn't really an object but a JSON. I've used the JSON.parse() function to make it an object and now I'm able to access to the fields using key.value syntax.
Perhaps you could use the chrome.storage to set/get the data rather than rely on the components state.
Otherwise can you share what the console.log(request) is giving you and what the background script looks like?

Azure Function outgoing storage queue binding not available on context

I have a really simple Azure Function with the sole purpose of taking all messages included in a blob and put those messages on a storage queue.
I'm running Functions 2.x, the function is written in JavaScript and I've registered a blob trigger and an output binding for storage queues.
The problem I'm having is that the output binding isn't available in ctx.bindings in my function. I'm using a named output binding, because I will have multiple output bindings. When I change the output binding name to $return and return my data, the messages are written to the queue as expected, but when I set a different name the binding doesn't show up in the context. I can however see the binding definition in ctx.bindingDefinitions.
I'm running the code locally with Azure Function Host, with the proper extensions installed.
My code goes like this:
import { Context } from '#azure/functions'
export async function run(ctx: Context , content: string): Promise<void> {
try {
const data = JSON.parse(content)
if (!ctx.bindings[data.queue]) {
throw new Error(`No output binding defined for queue '${data.queue}'`)
}
ctx.bindings[data.queue] = [...data.messages]
} catch (e) {
return Promise.reject(e)
}
}
And my function.json:
{
"disabled": false,
"bindings": [
{
"name": "content",
"type": "blobTrigger",
"direction": "in",
"path": "message-batches/{filename}.txt"
},
{
"type": "queue",
"direction": "out",
"name": "message",
"queueName": "message",
"connection": "AZURE_STORAGE_CONNECTION_STRING"
}
],
"scriptFile": "index.js"
}
My incoming content binding is available as ctx.bindings.content. I'm thinking I might be missing something trivial here, but what could be the reason for the binding not to show up under ctx.bindings?
The output binding is not available in Context.bindings until it's populated with content at runtime.
If we want to check the existence of output definition, turn to Context.bindingDefinitions.
let flag:boolean = false;
for (let bindingDefinition of ctx.bindingDefinitions) {
if(bindingDefinition.name == data.queue) {
flag = true;
break;
}
}
if(!flag){
throw new Error(`No output binding defined for queue '${data.queue}'`)
}

Shippo: Using generated transaction's label_url variable in other functions

I'm hoping someone with more experience working with Shippo's API in Node can help me figure this out.
My end goal is to press a button on an angular form front end, have the shipment transaction created, and use the transaction's label URL to create a custom PDF. Everything is working except for pushing the generated label URL to the PDF template.
First, I pasted Shippo's single click label creation example into an Express POST route. It worked just fine, generating transactions that I could check out by pinging Shippo's API for a list of recent transactions and viewing the most recent one.
Then, I added lines 102-111 of this code example and replaced the generic error message generator in the instalabel code with it, so my current app.js Shippo transaction logic looks like this:
shippo.transaction.create({
"shipment": shipment,
"carrier_account": "xxxxxxxxxxxxxxxxxxxxxx",
"servicelevel_token": "ups_ground",
"label_file_type": "PNG"
},function(transaction, err ){
console.log("transaction : %s", JSON.stringify(transaction, null, 4));
// print label_url and tracking_number
if(transaction.object_status == "SUCCESS") {
console.log("Label URL: %s", transaction.label_url);
console.log("Tracking Number: %s", transaction.tracking_number);
exports.label_url = transaction.label_url;
exports.tracking_number = transaction.tracking_number;
}else{
//Deal with an error with the transaction
console.log("Message: %s", transaction.messages);
}
});
I need to grab the label_url & tracking_number for the transaction that was just created and use it in another function, but everything I've tried so far seems to end up with an error like the following:
/src/app.js:88
if(transaction.object_status == "SUCCESS") {
^
TypeError: Cannot read property 'object_status' of null
I'm guessing this is because the function to create a shipping label isn't exporting the response Shippo is sending back, so I can't use it in other functions... Is that accurate, or am I barking up the wrong tree here? For reference, this is what Shippo's response is supposed to] look like:
{
"object_state":"VALID",
"object_status":"SUCCESS",
"object_created":"2014-07-25T02:09:34.422Z",
"object_updated":"2014-07-25T02:09:34.513Z",
"object_id":"ef8808606f4241ee848aa5990a09933c",
"object_owner":"shippotle#goshippo.com",
"was_test":true,
"rate":"ee81fab0372e419ab52245c8952ccaeb",
"tracking_number":"tracking_number_goes_here",
"tracking_status":null,
"tracking_url_provider":"",
"label_url":"label_url_goes_here",
"commercial_invoice_url": "",
"messages":[
],
"customs_note":"",
"submission_note":"",
"metadata":""
}
What can I do to use the values from this response outside the shippo.transaction.create function itself?
Thanks for reading.
The parameters you're passing to the callback used in shippo.transaction.create has its injected params reversed. It should be (err, transaction) not (transaction, err). Alternatively, you can chain on a .then() and pass a callback that only takes (transaction) and access any error messages in transaction.messages.
Below is a working example with the latest version of the shippo-node-wrapper at the time of this writing.
var shippo = require('./lib/shippo')('<API KEY>');
var addressFrom = {
"object_purpose":"PURCHASE",
"name":"Ms Hippo",
"company":"Shippo",
"street1":"215 Clayton St.",
"city":"San Francisco",
"state":"CA",
"zip":"94117",
"country":"US", //iso2 country code
"phone":"+1 555 341 9393",
"email":"ms-hippo#goshippo.com",
};
// example address_to object dict
var addressTo = {
"object_purpose":"PURCHASE",
"name":"Mr Hippo",
"company":"Happy Hippo",
"street1":"965 Mission St",
"street2":"Suite 425",
"city":"San Francisco",
"state":"CA",
"zip":"94103",
"country":"US", //iso2 country code
"phone":"949-123-4567",
"email":"mrhippo#goshippo.com",
"metadata" : "Hippo T-Shirt Order #1043"
};
// parcel object dict
var parcel = {
"length":"5",
"width":"5",
"height":"5",
"distance_unit":"in",
"weight":"2",
"mass_unit":"lb",
};
var shipment = {
"object_purpose": "PURCHASE",
"address_from": addressFrom,
"address_to": addressTo,
"parcel": parcel,
"async": false
};
shippo.transaction.create({
"shipment": shipment,
"carrier_account": "07280f4f96f34cc8b75e593c4835dc38",
"servicelevel_token": "usps_priority",
"label_file_type": "PNG"
}, function (err, transaction) {
console.log("transaction : %s", JSON.stringify(transaction, null, 4));
// print label_url and tracking_number
if (transaction.object_status == "SUCCESS") {
console.log("Label URL: %s", transaction.label_url);
console.log("Tracking Number: %s", transaction.tracking_number);
} else {
//Deal with an error with the transaction
console.log("Message: %s", transaction.messages);
}
});
// OR
shippo.transaction.create({
"shipment": shipment,
"carrier_account": "07280f4f96f34cc8b75e593c4835dc38",
"servicelevel_token": "usps_priority",
"label_file_type": "PNG"
}).then(function (transaction) {
console.log("transaction : %s", JSON.stringify(transaction, null, 4));
// print label_url and tracking_number
if (transaction.object_status == "SUCCESS") {
console.log("Label URL: %s", transaction.label_url);
console.log("Tracking Number: %s", transaction.tracking_number);
} else {
//Deal with an error with the transaction
console.log("Message: %s", transaction.messages);
}
});

Load JSON file from local PC in Nativescript

So I am having trouble displaying the contents of my JSON file in nativescript using console commands.I basically want to display these contents and use the values in the file to do some additional functions.
This is the JS function that I have slightly rewritten from the NS documentation and Emil Oberg's solution on a different post
var fs = require('file-system');
var documents = fs.knownFolders.documents();
var jsonFile = documents.getFile('/Users/student/Desktop/Native_Script/Library/app/images/status.json');
var array;
var jsonData;
//console.log('Item:' +jsonFile);
jsonFile.readText()
.then(function (content)
{
try {
jsonData = JSON.parse(content);
//console.log('Item:' + JSON.stringify(jsonData));
array = new observableArrayModule.ObservableArray(jsonData);
}
catch (err) {
console.log(err);
}
console.log('Item:' +JSON.stringify(jsonData));
});
////////////////
JSON File:
[{
"Status": "3",
"Trend": "increase",
"Space": "Gleason"
}, {
"Status": "2",
"Trend": "decrease",
"Space": "PRR"
}, {
"Status": "4",
"Trend": "stable",
"Space": "WBR"
}, {
"Status": "1",
"Trend": "decrease",
"Space": "HCR"
}]
So can someone tell where I am going wrong and how would I go about displaying any of the components of the file in the console. I essentially want to use one of the values in the file, say status, to call on another function.
So something like: (psuedocode)
status.getvalue
.then(function)
if status > 3
console.log (place is crowded)
Okay so here you're trying to read a file on your computer, from a device (iPhone/Android/Emulator/etc). This is simply not doable. The getFile call expects a path on the device.
So, either:
Store the JSON file on the device, or
Just require() the JSON file. E.g. var jsonFile = require('status.json') and it'll get read and parsed for you.
Add something like below code, might be your jsonFile.readText() is throwing error
p1.then(function(value) {
console.log(value); // "Success!"
throw 'oh, no!';
}).catch(function(e) {
console.log(e); // "oh, no!"
})
jsonFile.readText()
.then(function (content)
{
try {
jsonData = JSON.parse(content);
//console.log('Item:' + JSON.stringify(jsonData));
array = new observableArrayModule.ObservableArray(jsonData);
}
catch (err) {
console.log(err);
}
console.log('Item:' +JSON.stringify(jsonData));
})
.catch(function(e) {
console.log(e); // "oh, no!"
});

Categories

Resources