Handling HttpClient Http Errors at the Service Level - javascript

I have a shared service throughout my app that handles authentication, I'm trying to abstract my component logic as far from the http requests as possible, however, every bit of documentation I've seen appears to want me to return the httpClient Observable, and subscribe to it and perform all logic for handling the results and errors inside the component.
My current service code is completely broken, but it looks like this:
userLogin(email: String, password: String) {
const body = { email: email, password: password };
return this.httpClient.post('http://localhost/users/login', body).subscribe(
this.handleResults,
this.handleErrors
);
}
handleResults(results: any) {
if (results.errors) {
console.log(results.errors);
} else {
return results;
}
}
handleErrors(err: HttpErrorResponse) {
if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
console.log('A ', err.status, ' error occurred:', err.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.log('Could not connect to server.');
console.log('Backend returned code ' + err.status + ', body was: ' + JSON.stringify(err.error));
}
}
And ideally on the component module I'd have something like a callback function that is called when the response is ready. It seems like I'm trying to go against the grain with Angular patterns, but at the same time, I can't understand why Angular would require error handling for generic http errors do be performed at the Component level.
So I suppose the basic question is: how do I handle httpClient errors within the service, rather than in the individual components?

You can handle the errors in here, and still return the observable, like so
return this.httpClient.post('http://localhost/users/login', body).catch(this.handleErrors)

Related

onError Authentication with refresh token

In the Apollographql documentation it states:
The onError link can retry a failed operation based on the type of GraphQL error that's returned. For example, when using token-based authentication, you might want to automatically handle re-authentication when the token expires.
This is followed up by their sample code:
onError(({ graphQLErrors, networkError, operation, forward }) => {
if (graphQLErrors) {
for (let err of graphQLErrors) {
switch (err.extensions.code) {
// Apollo Server sets code to UNAUTHENTICATED
// when an AuthenticationError is thrown in a resolver
case "UNAUTHENTICATED":
// Modify the operation context with a new token
const oldHeaders = operation.getContext().headers;
operation.setContext({
headers: {
...oldHeaders,
authorization: getNewToken(),
},
});
// Retry the request, returning the new observable
return forward(operation);
}
}
}
// To retry on network errors, we recommend the RetryLink
// instead of the onError link. This just logs the error.
if (networkError) {
console.log(`[Network error]: ${networkError}`);
}
});
My question is in regards to the getNewToken(), as no code was provided for this function, I want to know (assuming this is another request to the backend and I am not sure how it could not be), if you are able to and or supposed to use query/mutation in graphql or make the request through axios for example.
One problem, if it can/should be a graphql query or mutation, is to get the new token, the onError code is defined in the same file as the ApolloClient as ApolloClient needs access to onError, thus when trying to implement this as retrieving a new token through a graphql mutation I got the following error:
React Hook "useApolloClient" is called in function "refresh" that is
neither a React function component nor a custom React Hook function.
After trying to useQuery/useMutation hook and realizing I cannot outside of a react component and at the top level I found this post whose answers suggested you can use useApolloClient.mutate instead but I still ran into issues. My code was (and tried multiple iterations of this same code like useApolloClient() outside of the function and inside etc.):
const refresh = () => {
const client = useApolloClient();
const refreshFunc = () => {
client
.mutate({ mutation: GET_NEW_TOKEN })
.then((data) => {
console.log(data);
})
.catch((err) => {
console.log(err);
});
};
refreshFunc();
};
I could capitalize Refresh but this still would not work and would break the rules of hooks.
And to clarify all the above would do is I would replace the console.logs with setting session storage to the retrieved new token and then re trying the original request with onError.
Now in another post I found when looking into this, the users getNewToken request was a rest request using axios:
const getNewToken = async () => {
try {
const { data } = await axios.post(
"https://xxx/api/v2/refresh",
{ token: localStorage.getItem("refreshToken") }
);
localStorage.setItem("refreshToken", data.refresh_token);
return data.access_token;
} catch (error) {
console.log(error);
}
};
Now from my understanding, if I wanted to implement it this way I would have to change my backend to include express as I am only using apolloserver. Now I could definitely be wrong about that as my backend knowledge is quite limited and would love to be corrected their.
So my question is, what is the best way to do this, whether natively using graphql queries/mutations (if possible), doing it with axios, or maybe their is another best practice for this seemingly common task I am unaware of.

How to read error messages from javascript error object

Could some one help me out on below question please :-)
I'm making a post call through redux action, which is below.
export const addEmployee = ({ firstName, surname, contactNumber, email }) => async dispatch => {
const payloadBody = JSON.stringify({ firstName, surname, contactNumber, email });
fetch('/api/users', {
method: 'POST',
body: payloadBody,
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
if (!response.ok) {
return response.text()
.then(text => {
throw Error(text)
});
} else {
dispatch(setAlert("New Employee added ", 'danger'));
}
})
.catch(error => {
console.log('>>> in CATCH block, error is =>', error);
console.log('>>> in CATCH block, error name is =>', error.name);
console.log('>>> in CATCH block, error message is =>', error.message);
let allKeys = Object.getOwnPropertyNames(error);
console.log(allKeys);
// const errors = [];
// Object.keys(error.message).forEach(key => {
// console.log('>>> key are ', key)
// })
// const keys = Object.keys(error.message);
// console.log(keys);
// const errors = error.message['errors'];
// const errors = error.response.data.errors;
// if (errors) {
// errors.forEach(error => dispatch(setAlert(error.msg, 'danger')));
// }
dispatch({
type: REGISTER_FAIL
});
})
}
Above post call on failure, returns body with error message, an example is below
{
"errors": [
{
"msg": "User already exist with email"
}
]
}
Question
What I'm trying to achieve is, to grab the errors[] and pass the error message through to a component, the trouble I have is accessing the error[] array within the returned array message. I'll describe below what I've attempted, it also can be seen in the redux action method I posted above.
Try-1
console.log('>>> in CATCH block, error is =>', error); yields just Error
Try-2
console.log('>>> in CATCH block, error name is =>', error.name); yields {"errors":[{"msg":"User already exist with email"}]} and the typeof this is string since I'm returning text() return response.text().then(text => { throw Error(text) })
Try-3
When I return as json() return response.json().then(text => { throw Error(text) })and console.log('>>> in CATCH block, error message is =>', error.message); yields object.
The questions again What I'm trying to achieve is, to grab the errors[] and pass the error message through to a component such as below
const errors = error.message; // this is where I'd like to extract the error.
if (errors) {
errors.forEach(error => dispatch(setAlert(error.msg, 'danger')));
}
Hope the above description is clear, please let me know if you require more info,
I know I'm missing some crucial knowledge of working with error objects, could someone please shed some light on this please :-)
Pattern for throwing errors recovered from standard-format HTTP payload
Your redux action does work over HTTP. Sometimes the server responds with bad news, and it seems like there's a standardized format the server uses to report that news. Also, sometimes your own code throws. You want to handle both kinds of problem with control structures related to Errors.
Basic pattern for an async Redux action
Before we start: your action is marked async, but you're still chaining .then and .catch. Let's switch to async/await, converting this:
export const addEmployee = (/*...*/) = async ( dispatch, getState ) => {
fetch(/* ... */)
.then(response => {
return response.text()
.then(text => {
// happy-path logic
throw Error(text)
})
})
.catch(error => {
// sad-path logic
dispatch(/* ... */)
})
}
...into this:
export const addEmployee = (/*...*/) = async ( dispatch, getState ) => {
try {
let response = await fetch(/* ... */)
let responseText = await response.text()
// happy-path logic
dispatch(/* ... */)
return // a redux action should return something meaningful
} catch ( error ) {
// sad-path logic
dispatch(/* ... */)
return // a failed redux action should also return something meaningful
}
}
Now let's talk about errors.
Error basics
Meet throw:
try { throw 'mud' } catch( exception ) { /* exception === 'mud' */ }
try { throw 5 } catch( exception ) { /* exception === 5 */ }
try { throw new Date() } catch( exception ) { /* exception is a Date */ }
You can throw just about anything. When you do, execution halts and immediately jumps to the closest catch, searching all the way through the stack until it finds one or runs out of stack. Wherever it lands, the value you provided to throw becomes the argument received by catch (known as an "exception"). If nothing catches it, your JS console logs it as an "uncaught exception."
You can throw anything, but what should you throw? I think you should only throw instances of Error, or one of its subclasses. The two main reasons are that the Error class does some helpful things (like capturing a stacktrace), and because one of your two sources of failure is already going to be throwing Error instances, so you must do something similar if you wish to handle both with a single codepath.
Meet Error:
try {
throw new Error('bad news')
} catch ( error ) {
console.log(error.message)
//> 'bad news'
}
We already know that an Error will be thrown if code within your action blows up, e.g. JSON.parse fails on the response body, So we don't have to do anything special to direct execution onto the catch path in those scenarios.
The only thing we have to be responsible for is to check whether the HTTP response contains something that looks like your server's "standard error payload" (more on that later), which your sample suggests is this:
{
"errors": [
{
"msg": "ERROR CONTENT HERE"
}
]
}
Here's the core issue
This handling has to be special because no javascript engine considers it an error simply to receive an HTTP payload that can be parsed as JSON and which contains a key named "errors". (Nor should they.) This payload pattern is merely a custom convention used by some or all of the HTTP endpoints that you talk to.
That's not to say it's a bad idea. (I think it's great!) But that explains why it must be done custom: because this pattern is just your private little thing, and not actually special in a way that would make browsers treat it the special way you want.
So here's our plan:
make the request, relying on try/catch to capture things thrown by our tools
if we get a response that seems bad:
examine the payload for an error encoded in the "standard format"; I call anything like this an "API error"
if we find an API error, we will create and throw our own Error, using the API error content as its message
if we don't find an API error, we'll treat the raw body text of the response as the error message
if we get a response that seems good:
dispatch the good news (and useful data) to the store
Here's what that looks like in code:
export const addEmployee = ({
firstName,
surname,
contactNumber,
email
}) => async ( dispatch, getState ) => {
const payloadBody = {
firstName,
surname,
contactNumber,
email
}
try {
// step 1
let response = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payloadBody)
})
let responseText = await response.text()
if (!response.ok) {
// step 2
let errorString = getErrorMessageFromResponseBody(responseText)
throw new Error(errorString) // API errors get thrown here
}
// step 3
let responseJson = JSON.parse(responseText)
dispatch(setAlert('New Employee added', responseJson.user.name))
/*
A redux action should always returns something useful.
addEmployee might return the `user` object that was created.
*/
return responseJson.user
} catch ( error ) {
// all errors land here
dispatch({
type: REGISTER_FAIL,
message: error.message
})
/*
A failed redux action should always return something useful (unless you prefer to throw).
For now, we'll return the reason for the failure.
*/
return error.message
}
}
function getErrorMessageFromResponseBody( string ) {
let errorString = string
try {
let json = JSON.parse(string)
if(json.errors) {
errorString = json.errors[0].msg
}
} catch ( parseOrAccessError ) {}
return errorString
}
Here's what can be thrown to that catch block:
anything thrown by JSON.parse when applied to the arguments
anything thrown by fetch
if !response.ok, the whole response payload (or just an error message if the payload contains an API error)
Exception handling
How can you tell those different kinds of failure apart? Two ways:
Some failures throw specific subclasses of Error, which you can test for with error instanceof SomeErrorClass:
JSON.stringify throws a TypeError if it can't serialize its argument (if you have custom .toJSON anywhere, it can also throw anything that throws)
fetch throws a TypeError if it can't reach the internet
JSON.parse throws a SyntaxError if the string can't be parsed (if you use a custom reviver, those errors get thrown too)
Any instance of Error or its subclasses will have a .message; you can test that string for specific cases
How should you handle them?
If JSON.stringify blows up, it's because you wired your data wrong. In that case, you probably want to do something that will alert the developer that something is broken and help diagnose the issue:
console.error(error)
dispatch some failure action that includes the error.message
show a generic error message on-screen
If fetch throws, you could dispatch a failure that presents a "fix your wifi" warning to the user.
If JSON.parse throws, the server is melting down, and you should show a generic error message.
A little sophistication
Those are the basic mechanics, but now you confront a messy situation. Let's list some challenges:
You may have already noticed one problem: "no internet" will present the same way as "circular data": a thrown TypeError.
It turns out that the precise text of JSON.stringify errors depends on the actual value supplied to that function, so you can't do something like error.message === CONSTANT_STRINGIFY_ERROR_MESSAGE.
You may not have an exhaustive list of every msg value the server can send in an API error.
So how are you supposed to tell the difference between a problem reported by a sane server vs a client-side bug vs a broken server vs unusable user data?
First, I recommend creating a special class for API errors. This lets us detect server-reported problems in a reliable way. And it provides a decent place for the logic inside getErrorMessageFromResponseBody.
class APIError extends Error {}
APIError.fromResponseText = function ( responseText ) {
// TODO: paste entire impl of getErrorMessageFromResponseBody
let message = getErrorMessageFromResponseBody(responseText)
return new APIError(message)
}
Then, we can do:
// throwing
if (!response.ok) {
// step 2
throw APIError.fromResponseText(responseText)
}
// detecting
catch ( exception ) {
if(exception instanceof APIError) {
switch(APIError.message) {
case 'User already exist with email':
// special logic
break
case 'etc':
// ...
}
}
}
Second, when throwing your own errors, never provide a dynamic string as the message.
Error messages for sane people
Consider:
function add( x, y ) {
if(typeof x !== 'number')
throw new Error(x + ' is not a number')
if(typeof y !== 'number')
throw new Error(y + ' is not a number')
return x + y
}
Every time add is called with a different non-numeric x, the error.message will be different:
add('a', 1)
//> 'a is not a number'
add({ species: 'dog', name: 'Fido' }, 1)
//> '[object Object] is not a number'
The problem in both cases is that I've provided an unacceptable value for x, but the messages are different. That makes it unnecessarily hard to group those cases together at runtime. My example even makes it impossible to tell whether it's x or y that offends!
These troubles apply pretty generally to the errors you'll receive from native and library code. My advice is to not repeat them in your own code if you can avoid it.
The simplest remedy I've found is just to always use static strings for error messages, and put some thought into establishing conventions for yourself. Here's what I do.
There are generally two kinds of errors:
some value I wish to use is objectionable
some operation I attempted has failed
In the first case, the relevant info is:
which datapoint is bad; I call this the "topic"
why it is bad, in one word; I call this the "objection"
All error messages related to objectionable values ought to include both datapoints, and in a manner that is consistent enough to facilitate flow-control while remaining understandable by a human. And ideally you should be able to grep the codebase for the literal message to find every place that can throw the error (this helps enormously with maintenance).
Here is how I construct the messages:
[objection] [topic]
There is usually a discrete set of objections:
missing: value was not supplied
unknown: could not find value in DB & other "bad key" issues
unavailable: value is already taken (e.g. username)
forbidden: sometimes specific values are off-limits despite being otherwise fine (e.g. no user may have username "root")
invalid: heavily overused by dev community; treat as option of last resort; reserved exclusively for values that are of the wrong datatype or syntactically unacceptable (e.g. zipCode = '__!!#')
I supplement individual apps with more specialized objections as needed, but this set comes up in just about everything.
The topic is almost always the literal variable name as it appears within the code block that threw. To assist with debugging, I think it is very important not to transform the variable name in any way.
This system yields error messages like these:
'missing lastName'
'unknown userId'
'unavailable player_color'
'forbidden emailAddress'
'invalid x'
In the second case, for failed operations, there's usually just one datapoint: the name of the operation (plus the fact that it failed). I use this format:
[operation] failed
As a rule, operation is the routine exactly as invoked:
try {
await API.updateUserProfile(newData)
} catch( error ) {
// can fail if service is down
if(error instanceof TypeError)
throw new Error('API.updateUserProfile failed')
}
This isn't the only way to keep your errors straight, but this set of conventions does make it easy to write new error code without having to think very hard, react intelligently to exceptions, and locate the sources of most errors that can be thrown.
Handling server inconsistencies
A final topic: it's pretty common for a server to be inconsistent about how it structures its payloads, particularly with errors but also with successes.
Very often, two endpoints will encode their errors using slightly different envelopes. Sometimes a single endpoint will use different envelopes for different failure cases. This is not usually deliberate, but it is often a reality.
You should coerce all the different flavors of server complaint into a single interface before any of this madness can leak into the rest of your application, and the shore of the client/server boundary is the best place to immediatley jettison server weirdness. If you let that stuff escape into the rest of your app, not only will it drive you insane, but it will make you brittle by allowing the server to surface errors deep inside your app, far away from the real source: a violated API contract.
A way to support a variety of envelopes is by adding extra code to getErrorMessageFromResponseBody for each of the different envelopes:
function getErrorMessageFromResponseBody( string ) {
let errorString = string
/*
"Format A"
{ errors: [{ msg: 'MESSAGE' }] }
used by most endpoints
*/
try { /*... */ } catch ( parseOrAccessError ) {}
/*
"Format B"
{ error: { message: 'MESSAGE' } }
used by legacy TPS endpoint
*/
try { /*... */ } catch ( parseOrAccessError ) {}
/*
"Format C"
{ e: CODE }
used by bandwidth-limited vendor X
use lookup table to convert CODE to a readable string
*/
try { /*... */ } catch ( parseOrAccessError ) {}
return errorString
}
One of the values of having a dedicated APIError class to wrap these things is that the class constructor provides a natural way to gather all this up.

How to find the Error message in Error object send by NodeJS in Angular

The Nodejs functions return an error from try/catch scope, such as the one below if the user doesn't exist of if a database is not reachable:
router.delete('/delete/:email', async (req, res) => {
var email = req.params.email;
try {
let result = await User.remove({"email": email});
res.status(204).send(email);
} catch (err) {
res.status(400).send(err);
}
});
I can also return the Error from Nodejs server by myself:
return res.status(400).send(new Error(`The user with email ${email} doesn't exist.`));
The first problem is that I can't find the error message that is embedded somewhere deep in the body the returned Error object. It is stored in one of its 100+ attributes. Where should I look for it so I could display in on a screen for the end user to read it?
Then, the err object generated by the try/catch scope has a set of different attributes comparing to the Error object created with new Error("Here is my error message"). Is there a way to normalize the returned Errors so they all have the same or similar attributes?
You don't need to return the whole error object from the server, and arguably shouldn't since error messages can expose internals about your code and infrastructure.
One way you could handle this is to format and return an error message from the server yourself. Assuming you're using express this would look something like:
return res.status(400).json({ message: `The user with email ${email} doesn't exist.` });
Alternatively you could use an error handling middleware like strong-error-handler found here: https://github.com/strongloop/strong-error-handler which automatically builds a json formatted message that's easier to parse, but keep in mind that the content of the message differs depending on whether you set debug mode to true or no.
If you want to develop a secure web application with nice error handling, i will suggest you the following structure.
Step 1. At front end divide your api calls in four main operations for e.g. inset,update,query and filter.
now whenever your page loads and you want to show some data fetched from server then your api call must be like 'https://domainname.tld/server/query' and send some payload with this api call according to need of your data requirements to be fetched.
At backend probably at Server.js handle like this :
app.all("/server/query", function (req, res) {
try {
console.log(a);
// some database or io blocking process
} catch (error) {
// error handling
var err = writeCustomError(error.message || error.errmsg || error.stack);
res.status(417).json(err).end();
}
});
function writeCustomError(message) {
var errorObject = {};
errorObject.message = message;
errorObject.code = 10001; // as you want
errorObject.status = "failed";
return errorObject;
}
in try block you can also handle logical errors using same function i.e writeCustomError
So if you use this approach you can also implement end-to-end encryption and send only eP('encrypted payload') and eK('encryption Key'),by doing this end users and bad end users even can not evaluate your serve API calls.
If you are thinking how will you route different paths at server then simplest solution is send uri in payload from client to server for e.g
User wants to reset password :-
then
call api like this
https://domain.tld/server/execute and send Json object in payload like this {uri:"reset-password",old:"",new:""}.
at backend
use
app.all("/server/execute", function (req, res) {
try {
// decrypt payload
req.url = payload.uri;
next();
} catch (error) {
// error handling
var err = writeCustomError(error.message || error.errmsg || error.stack);
res.status(417).json(err).end();
}
});
app.all("/reset-password", function (req, res) {
try {
// reset logic
} catch (error) {
// error handling
var err = writeCustomError(error.message || error.errmsg || error.stack);
res.status(417).json(err).end();
}
});
so in this way only developer know where password reset logic and how it can called and what parameters are required.
I will also suggest you to create different router files for express like QueryRouter,InsertRouter etc.
Also try to implement end-to-end encryption.Any query regarding post,kindly comment it.

Angular 2 Http get not triggering

As said in the title, nothing is happening when I subscribe to my observable. There is no error in the console or during the build. Here is my code :
My service
getBlueCollars(): Observable<BlueCollar[]> {
return this.http.get(this.defaultAPIURL + 'bluecollar?limit=25').map(
(res: Response) => {
return res.json();
});
}
My component
ngOnInit() {
this.planifRequestService.getBlueCollars().subscribe(
data => {
this.blueCollars = data;
console.log('Inner Blue Collars', this.blueCollars);
},
err => console.log(err)
);
console.log('Value BlueCollars : ', this.blueCollars);
}
So the second console.log is triggering with "Value BlueCollars : Undefined", and the log in my subscribe is never showed. As well, I can't see the request sent in the Networt tab of Chrome.
So I tried to simplify everything with the following code :
let response: any;
this.http.get('myUrl').subscribe(data => response = data);
console.log('TestRep: ', response);
Same problem here, no error, response is undefined. It seems the subscribe is not triggering the observable. (The URL is correct, it is working on my swagger or with postman.)
I'm on Angular 2.4.9
Edit
So I tried to copy/past the code of my request on a brand new project, everything is working fine. The request is triggered and I can get the JSON response correctly. So there is something maybe on the configuration of my project that is forbiding the request to trigger correctly.
Ok just found what was going on. I am using a fake backend in order to try my login connexions that is supposed to catch only specified URL. However for wathever raison it was catching all the requests, so that explain everything. Thx for your help everybody.
Try adding a catch block to your service code:
getBlueCollars(): Observable<BlueCollar[]> {
return this.http.get(this.defaultAPIURL + 'bluecollar?limit=25')
.map(
(res: Response) => {
return res.json();
})
.catch(err => Observable.throw(err))
}
Don't forget to
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';`
I imagine this will result in the error that'll give you an idea where your code is going wrong.
The reason the console.log outside the subscribe call is undefined is because the subscribe/http call is happening asynchronously and so, in effect, the order (in time!) the code is running is:
1) the observable is subscribed to (and then waits for a response)
2) the outer console log runs with blueCollars undefined
3) when the response (or error) comes back from the http request (potentially after several seconds), only then will the inner assignment of this.blueCollar = data happen (and the inner console log), OR an error will get logged
Apart from that the subscribe code looks fine...!

Parse custom webhook: can I query my tables?

In a Parse custom webhook, which is of the form:
app.post('/receiveSMS', function(req, res) {
Where receiveSMS is hooked up to the Twilio api and this method is properly called (I have logs to prove it), but I'm trying to query on my tables within this method and it doesn't seem to be working.
Is this allowed, or is there anything special I need to do to make this work?
var contactObj = Parse.Object.extend("Contact");
var contactQuery = new Parse.Query(contactObj);
console.log(req.body.From);
contactQuery.each(function(contact) {
and the body of the each call never gets called.
Is this allowed, and if so, what am I doing wrong here?
Update -- The entirety of the webhook code block is:
app.post('/receiveSMS', function(req, res) {
console.log('receive SMS');
console.log(req.body.Body);
res.send('Success');
if(req.body.Body.toLowerCase() == "in" || req.body.Body.toLowerCase() == "out") {
twilio.sendSMS({
From: "(xxx) xxx-xxxx",
To: req.body.From,
Body: "It's been noted, and notifications have been sent. Check us out!"
}, {
success: function(httpResponse) {
console.log(httpResponse);
response.success("SMS Sent!");
},
error: function(httpResponse) {
console.error(httpResponse);
response.error("Uh OH, something went wrong");
}
});
if(req.body.Body.toLowerCase() == "in") {
console.log("in was received");
// eventQuery
var contactObj = Parse.Object.extend("Contact");
var contactQuery = new Parse.Query(contactObj);
console.log(req.body.From);
// contactQuery.equalTo("phone", req.body.From);
contactQuery.first({
success: function(contact) {
console.log("found contact");
console.log(contact);
}, error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
}
}
});
This code is called and the logs "console.log('receive SMS')" and the like are all called, except for what is inside the query's first call.
Queries on tables is fine, but you can't use the each() function, as that is restricted to only work in background jobs.
You'll have to use find() or first() or get() depending on your needs.
UPDATE
OK, after seeing your full code I have some ideas as to why it isn't working. First off you're sending res.send("Success"); before you're finished, I'm not positive but I think this causes it to stop running the rest of your code (haven't checked, could be wrong).
Also you're doing multiple async operations without chaining them so the contactQuery.first() will run before the twilio.sendSMS() is finished.
Inside twilio.sendSMS() you're calling response.success() / response.error(). These are for cloud methods, not web hooks, so I expect these would be throwing errors server-side (check the logs on the Dashboard).
Inside contactQuery.first() you are using alert() which isn't supported in cloud code.
I'm not sure if those mistakes will be caught early and throw errors or if they'll raise run-time exceptions, but they should be fixed, your code re-deployed and try again. Then report any errors in the server logs.
Yes, it's allowed, I'm using the same web hooks.
My guess is that you probably have defined security restriction on your Contact class that prevent the query to fetch anything. What's the security setting on this class ?
You can either try to relax the constrains, or login as a dummy user, and execute the query (approach that I chose).
cheers
-A

Categories

Resources