How best to "return an error" from a Worklight procedure? - ibm-mobilefirst

I have written an adapter with a few simple procedures. In some circumstances I need to signal the caller that something went wrong. I have tried a few approaches ..
Throwing an exception: the text of the exception gets back to the caller via the onFailure callback (great), but comes wrapped in the module name and line number of the exception. TMI.
Returning an object where isSuccessful = false: this works like a charm and it's delivered to the caller via the onFailure callback.
For example:
return {
isSuccessful: false,
errors: ["No servers available"]
};
This article from IBM however explicitly warns against doing just this, though doesn't describe an alternative - can you?

Have you looked at this blog post?
https://www.ibm.com/developerworks/community/blogs/worklight/entry/handling_backend_responses_in_adapters?lang=en
The blog post details:
For invokeProcedure (client to adapter):
What does an invocation response look like?
When will isSuccessful be true?
When will isSuccessful be false?
For invokeHttp (adapter to server):
What does a backend invocation response look like?
When will isSuccessful be true?
When will isSuccessful be false?
Based on the conditions you will provide in the response to the client, you can then return errors in more clarity.

Related

Behaviour of RETURN parameter of BAPI_GOODSMVT_CREATE?

I am using bapi_goodsmvt_create to post in migo transaction code.
The parameter return is not returning any value when the postings are successful.
Is return supposed to return only error messages? Or both error and success messages?
That is exactly how it works, if there are no errors, the RETURN table will be empty. The FM BAPI_GOODSMVT_CREATE is well documented:

ASP.NET Core Web API - Return a string message with a NoContent Response?

I have some records in the database that may or may not have some information for a certain column, and that's OK.
If a consumer of the endpoint runs into one of these records, I'd like to return "NoContent", because, well, there's No Content for that record that we can execute on. BUT ... I'd like to give them a message why, as there are two distinct reasons.
When looking at other status codes, this works:
return Accepted("I SEE THIS STRING!");
It actually shows up in the Response Header as the field location (I think, don't make me run this project again!)
This works for say Internal Server error:
return StatusCode(500, "I SEE THIS TOO!");
But, for NoContent there is no constructor like Accepted, where you can pass an object. Also, this shows me no string whatsoever:
return StatusCode(204, "WHY CAN'T I SEE THIS STRING?!");
Help!
204 (No Content) returns an HttpResponseMessage with, well, No Content.
If you do have content to return that the user can consume (the two reasons), then you don't have a No Content scenario.
Perhaps an Ok (200) with a custom ContentNotProvided class that holds a message, which can be consumed by the client, will do the trick?
Alternatively, return a BadRequest (400) with a message.

How to tell whether Accounts.addEmail succeeded or failed, and if it failed, the reason why

I have a page where the user can type in a new email address and then this method attempts to add it to their account:
Meteor.methods({
add_new_email: function(address)
{
Accounts.addEmail(Meteor.userId(), address);
}
});
I'm using the accounts-password package in Meteor.
I'd like to give the user meaningful feedback after they try to add the new address, in particular if it failed why did it fail? I have looked at the docs but there doesn't seem to be any method to find out failure reason.
I know that I can count the user's email addresses before and after trying to add the new one, but that doesn't tell me if the address already belongs to another user, or if it's an existing address of the user's, or whatever is the failure reason.
Is there any way to find out the result of an API call like this?
You can read the information about what this method does here:
https://github.com/meteor/meteor/blob/master/packages/accounts-password/password_server.js#L847
As you can see, the method will fail only in one case:
The operation will fail if there is a different user with an email
only differing in case
Therefore if the method fails you can tell to the user that the email is already registered.
After experimenting some more, it seems that all I need to do is add a callback to my client when I call the method, and check there for an error. Any error is automatically returned to the callback.
Server:
Meteor.methods({
add_new_email: function(address)
{
Accounts.addEmail(Meteor.userId(), address);
}
});
Client:
Meteor.call('add_new_email', 'me#example.com', function(error){
if (error) console.log("got an error " + error.reason);
});
I had not realised that the error from the API would be passed up into my method. Meteor - it's always more clever than I expect!
Note also that you can use Meteor.Error in your methods to throw errors which will be passed up to client callbacks in exactly the same way, see the docs:
if (!Meteor.userId()) {
throw new Meteor.Error("not-authorized", "You must be signed in to write a new post");
}
I know I'm a bit late to the party but I ran into this problem today and found your post.
I needed to be able to tell on the server side whether it failed or not so what I did was put it in a try-catch like so:
let addSucceeded = false;
try{
Accounts.addEmail(user._id, newEmailAddress);
addSucceeded = true;
} catch(err) {}
console.log(addSucceeded);
Only if the Accounts.addEmail does not fail will addSucceeded be set to true. To make sure I don't run into the "fail because it replaced the same user's email address in a different case" scenario, I always toLowerCase() the email address when saving.

django-rest-framework custom error message as response

For my API, I need to respond every request's error with HTTP 200 and a JSON content. So instead of, responding with this:
Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
I'd like to do this:
res = {"code": 400, "message": "Bad Requset"}
Response(res)
Where is the best place to put such thing and how? In Serializer, Renderer, Exception? I need to catch every exception that serializer might throw as well as custom exception that I have written.
You may use status code 200 and with data=json.dumps(...), something like this:
res = {"code": 400, "message": "Bad Requset"}
return Response(data=json.dumps(res), status=status.HTTP_200_OK)
In terms of where to handle the exception, RestFramework has it covered, read Exceptions - Django REST framework, you can create a custom handler and do so.
However as api end points normally will be per view base, I would personally recommend create a custom decorator to wrap your views and return such Response in case of error.
Or, if you really want to return same response on ALL errors, then follow RestFramework doc and customise your error handling should be the best practice.
Hope this helps.

Nest1.0: ConnectionStatus error handling

I have a question regarding to Nest1.0pr and the connection error handling. In the previous versions of Nest I was using IResponse.ConnectionStatus.Error. It seems to me that the property Error does not exist in the new version anymore. However in the documentation I found the following:
ConnectionStatus is the response as it was returned by
Elasticsearch.net. It's section on handling responses applies here as
well.
And in the very section the property Error is mentioned.
Error When a call succeeds but does not return a http status code of
200 this property will have details on the error. Read more about
error handling here
So is the recommended way to check whether the property Success is false?
TIA
This changed when NEST was refactored to use Elasticsearch.Net. Now when a request fails, you can try checking the IResponse.ConnectionStatus.OriginalException property, which will contain the actual Elasticsearch error.