APIClient?.update(Record, completion: { response, error in
dLog(response)
dLog(error)
})
We've been trying to work through a buggy API that is provided by another company. Sometimes, the API works and I get a response record. Occasionally, the update disappears into a blackhole and completion never gets called, so I don't get an error either.
Ultimately we want the API to be fixed, but what is the correct way to catch this in the meantime so I can popup an alert?
I've used XCTest/expectation/waitFor, but I think that's mainly for Unit Testing, not sure if that could apply here.
Related
I have an actions project built and working. I'm trying to handle some error scenarios where it is failing. I need some help there.
I have a scenario where the webhook call throws a proper JSON formatted error response as shown below but which couldn't not be read at google end. Not sure if that is google actions limitation. Because of this issue I couldn't trigger a webhook handler back to my server to end the open conversation smoothly.
{
“responseJson”: {
“error”: {
“message”: “Transaction cancelled: maximum execution time exceeded”,
“detail”: “Transaction cancelled: ****”
},
“status”: “failure”
}
}
In the Error & status handling of actions scenes I dont see any system intent other than Cancel to handle any such error scenarios, I don't see any other relevant system intents too.
In simple words, I'm trying to catch a bad response and trigger back a webhook call to end the conversation at server side.
Could someone suggest a way to deal with this issue?
I want to insert a case and send error using addError() method in salesforce in Before update trigger.But using addError method case getting rolled back.
In Before update
if(condition)
Insert a case
acc.addError()enter code here
}
}
That's how it works. You can't have transaction succeed (save successfully) and throw exception at same time.
If you want to save the case but show something to user consider setting some field on it, sending email, making a Task user has to complete, Chatter post maybe.
Or make custom UI piece (lightning web component?) and there you could for example abuse record-edit-form's onsuccess handler to display red toast if you want. That'll be just UI thing though, Data Loader and integrations won't care.
I've been playing around with building some realtime functionality using Sails.js version 0.10-rc5 (currently the #beta release).
To accomplish anything, i've been following the sweet SailsCast tutorial on this subject (sailsCast link)
It talks about subscribing to a model via a 'subscribe' action within the model's controller. Then listening to it at the client side, waiting for the server to emit messages. Quite straightforward, although I do not seem to receive any messages.
I'm trying to do this to get real-time updates on anything that changes in my User models, or if new ones get created.. So I can display login status etc. in real time. Pretty much exactly the stuff that's explained in the sailsCast.
In my terminal i'll get two things worth noticing, of which the first is the following:
debug: Deprecated: `Model.subscribe(socket, null, ...)`
debug: See http://links.sailsjs.org/docs/config/pubsub
debug: (⌘ + double-click to open link from terminal)
debug: Please use instance rooms instead (or raw sails.sockets.*() methods.)
It seems like the 'subscribe' method has been deprecated. Could anybody tell me if that's correct, and tell me how to fix this? I've been checking out the reference to the documentation in the debug message, although it just points me to the global documentation page. I've been searching for an answer elsewhere, but haven't found anything useful.
The second message I'm getting is:
warn: You are trying to render a view (_session/new), but Sails doesn't support rendering views over Socket.io... yet!
You might consider serving your HTML view normally, then fetching data with sockets in your client-side JavaScript.
If you didn't intend to serve a view here, you might look into content-negotiation
to handle AJAX/socket requests explictly, instead of `res.redirect()`/`res.view()`.
Now, i'm quite sure this is because I have an 'isAuthenticated' policy added to all of my controllers and actions. When a user is not authenticated, it'll redirect to a session/new page. Somebody must log in to be able to use the application. When I remove the 'isAuthenticated' policy from the 'subscribed' action, the warnings disappear. Although that means anyone will get updates via sockets (when I get it to work), even when they're logged out. - I don't really feel like people just sitting at the login screen, fishing out the real time messages which are intended only for users who are logged in.
Can anyone help me getting the real time updates to work? I'd really appreciate!
As far as the socket messages not being received, the issue is that you're following a tutorial for v0.9.x, but you're using a beta version of Sails in which PubSub has gone through some changes. That's covered in this answer about the "create" events not being received.
Your second issue isn't about sockets at all; you'll just need to reconsider your architecture a bit. If you want to to use socket requests to sign users in, then you'll have to be more careful about redirecting them because, as the message states, you can't render a view over a socket. Technically you could send a bunch of HTML back to the client over a socket, and replace your current page with it, but that's not very good practice. What you can do instead is, in your isAuthenticated policy, check whether the request is happening via sockets (using req.isSocket) and if so, send back a message that the front end can interpret to mean, "you should redirect to the login page now". Something like:
module.exports = function (req, res, next) {
if ([your auth logic here]) {
return next();
}
else {
if (req.isSocket) {
return res.json({status: 403, redirectTo: "/session/new"});
} else {
return res.redirect("/session/new");
}
}
}
I am trying to setup some ServiceListeners, in particular two:
zeroConf.addServiceListener("100.1.168.192.in-addr.arpa.", myListener);
zeroConf.addServiceListener("_workstation._tcp.local.", myListener);
Whenever I do this, I get callbacks for myListener on serviceResolved() and serviceAdded() for all services that match "_workstation._tcp.local." However, I get no callbacks for "100.1.168.192.in-addr.arpa." ... despite the fact that jmDns sends out the queries, and a response comes back! I've attached a tcpdump of the request packets that jmdns sends out, and the response that comes back for it. However, the callbacks are not called so I never see the response in my application.
Does anyone know why this might be happening?
http://users.ece.cmu.edu/~gnychis/jmdns_nocallback.pcap
After some debugging of the actual event type that comes in, the event type resolves to "_tcp.in-addr.arpa." Adding this to my service listeners triggers the call back.
My code is for sending Emails to multiple users.User will click on send button,and rpc will be called. Now if user clicks on Cancel button .Ongoing rpc should be cancelled. . Can anyone help ?
I googled a lot, they have introduced the concept of Request Builder. But I am not getting any perfect idea.
Make your async method return a Request instead of void so you can call cancel() on it.
For the same reason, asynchronous methods do not have return types; they generally return void. Should you wish to have more control over the state of a pending request, return Request instead.
— Source: https://developers.google.com/web-toolkit/doc/latest/DevGuideServerCommunication#DevGuideCreatingServices
FYI, you can also use RequestBuilder as the return type, you'll then have to call the send() method by yourself (after possibly customizing the request, e.g. adding headers) to actually make the request to the server.
And of course, if you need to tell the server to abort the processing, you'll have to make another RPC call.
The request is asynch, so the client side can do anything it wants.
All you need to do is add a flag to indicate that the request should be cancelled, and then change the onSuccess method to check the flag and do nothing if it is set.
You should clear the requestCancelled flag each time you make a request - or else after the first request is cancelled, you won't be able to make another one...
e.g.
boolean requestCancelled = false;
void onSuccess(...)
{
if (!requestCancelled) {
// actual response handing code
}
}
If you really want to cancel the request on the server side, it is a lot more complicated. You could do this by sending a second request - one where the fuinctionality is to cancel a request.
To make this work, the "cancel request" has to set a field somewhere the "email request" can read. The "email request" needs to check if the "cancel field" has been set.
// server side Impl
void cancelRequest()
{
// You need to implement this class and ensure it really is a singleton
// and thread safe.
RequestStatusSingleton.setCancelled(true);
}
void serverSideEmailFunc()
{
while(modeEmailAddrs && ! RequestStatusSingleton.getCancelled()) {
// get next address and send email
}
}
Obviously this is a lot of work. Have you considered:
Not having a cancel button on your GUI?
Getting the server to process emails a few at a time (i.e. client sends multiple requests until server tells the client all emails are done).
I totally understand your user. No one wants to wait for 15 seconds.
There is no standard way to "kill" the request, because there is no way to know where your server/datastore is in implementing it. Unless you deal with a process that can be put in a single transaction that can be rolled back, you will have to implement your own logic. For example, if you asked the server to save an entity, you will have to tell the server to save this entity again, but this time without the changes.
Also, think again about your use case. Why a user wants to kill the request? May be he simply wants to go to another place in the app. Then there is no need to kill the request: when the response arrives, check if the user is still in the same place patiently waiting. If not, do not execute onSuccess().