When to present NSError - ios

I have a general question- what are some guidelines for handling NSError's? For instance, NSJSONSerialization can return an error creating JSON objects or JSON data.
I feel like it's (maybe) not appropriate to alert the user in this case? But the error message is still important.
So I'm not sure when and where the best place to handle obscure, non-user related errors?

This totally depends on the context in which error is thrown.
Per Apple Documentation:
Recover if Possible or Display the Error to the User
The best user experience is for your app to recover transparently from
an error. If you’re making a remote web request, for example, you
might try making the request again with a different server.
Alternatively, you might need to request additional information from
the user such as valid username or password credentials before trying
again.
So, there are cases, where you would want error to be obscured from user with potential fall back on error recovery path.
And there are cases, where you would want to let user know of the error occurred and take a corrective measure.
At the same time, in many situations, as a programmer we want to log error on console so we could fix them while testing.
As a side note, there are plenty of cases where we throw custom NSError objects and handle them with alerts, logging or other ways!
It is worth going through the shared Apple Documentation link, I believe!

Related

What are best practices for dealing with application errors caused by bots?

Every day I have bots hitting my application with random urls, which results in application errors. Because they try urls like https://smashnotes.com/p/*/e/*/s/* , I cannot entirely suppress this error from showing up again because if I do, it causes legitimate errors to go unseen. But I also don't want to rush to my phone every time there's a notification from Honebadger telling me there's an error, only to find out it's yet another fake hit.
I am thinking I should just write an exception loop that if parameters are missing, or they don't match any existing parameters, then redirect to the root. This way it won't exactly count as an error. There is a small chance that I will miss some legitimate errors too, like when the path urls are missing, or params were passed incorrectly. Maybe I can log those, and check them occasionally, but not have to be continuously alerted.
How would you solve these bot errors?
Could you be more specific with what those params means? If p, e, s are actually params or just random stuff aswel?
Without much information about the state of your application I can only suggest you to use :constraints at your route definition allied with a regexp to ensure that params hitting are in an appropriate format.
Rails guide

CloudKit - which CKErrors should be handled as .partialFailure, and should they also be handled as a non-partial failure?

I've got my basic CloudKit sync engine built and working correctly and I now I am fleshing out my error handling. I'd like a comprehensive list of which errors are possible per record when you receive a .partialFailure response code.
The documentation has a list of all the error codes, but in my searching it hasn't been obvious (to me) which are potentially going to show up inside the partialErrorsByItemID dictionary and which are going to show up only as error codes (or if they can show up as both, maybe when sending only one record?).
In the Apple CloudKit Share code example there is a CloudKitError class to handle errors, and that handles the following partial errors:
.serverRecordChanged
.zoneNotFound
.unknownItem
.batchRequestFailed
but I don't believe that is exhaustive as the rest of the class isn't exhaustive in handling errors that aren't .partialFailure. Surely .invalidArguments would be a possible partial failure error?
Here's what I would guess I need to cover:
.alreadyShared (if sharing)
.assetFileModified (if using Assets)
.assetFileNotFound (if using Assets)
.batchRequestFailed
.constraintViolation
.invalidArguments
.referenceViolation (if sharing)
.serverRecordChanged
.unknownItem
.zoneBusy?
.zoneNotFound
And finally, because these are handled as partial errors, do I also need to handle them as possible error code responses from CloudKit, in the same way I handle non-partial error codes like .serviceUnavailable? I am not using the CKDatabase convenience methods, I'm using the full operations like CKModifyRecordsOperation, if that matters?
Thanks in advance!
In CloudKit, you have convenience API and Batch Operations API. If you are only using the convenience API in your app, this means that you add/update/fetch/delete a single record at a time. Thus, you will never get CKErrorPartialFailure because you are NOT communicating with iCloud Server in batches. If you are using only Batch Operations API in your app, then you will get CKErrorPartialFailure. It is a high-level error that actually contains a sub-error (CKError instance) for each record/zone/subscription included in your operation.
I agree with you that the documentation is not clear what could occur only as a partial error and what could not. Plus what could occur in either case. To answer this question, you can take a simple approach by assuming that all errors might occur in both cases or you either another more detailed oriented approach by finding out the possible cases for each error.
For the second approach, I had to simulate different error scenarios and see which errors I get from the iCloud server. Please take the following points into consideration:
Try as many CKOperation as you can to get list of errors. You have operations for records, zones, database, subscriptions.
Is the operation atomic or not?
Some errors are impossible to simulate because we don't control iCloud Server responses by any means. Example: CKInternalError, CKServerRejectedRequest
Some errors would only occur during Development phase and should not occur during Production phase. Example: CKBadContainer,CKMissingEntitlement,CKBadDatabase
Some errors are clearly non-partial errors because they are more related to the whole request sent to iCloud. Examples: CKIncompatibleVersion, CKServiceUnavailable, CKRequestRateLimited, CKOperationCancelled, CKLimitExceeded, CKServerResponseLost, CKManagedAccountRestricted
Some errors can only occur as partial errors. Example CKBatchRequestFailed. This one only occur for atomic CKOperations
Some errors can occur as both partial/non-partial errors. Examples: CKNotAuthenticated, CKNetworkUnavailable, CKNetworkFailure. They occur as a partial error for record zone operations while they occur as non-partial error for records operations.
Some Zone related errors will appear as partial errors when using Batch Operations API. Examples:CKUserDeletedZone , CKZoneBusy. Exception: CKChangeTokenExpired I got it as a non-partial error when I was performing an operation-based call.
CKZoneNotFound occurs as a partial and non-partial error. If you use CKModifyRecordsOperation to upload to a non-existing zone, you will get a partial error. However, if you use CKFetchRecordZoneChanges to fetch from a non-existing zone, you will get non-partial error.
Merge Conflicts errors occur as a partial error when using Batch Operations API.
In WWDC 2015 Video, CKInvalidArguments was mentioned as one of the errors that might occur as partial error when using Batch Operations API. However, I tried different error scenarios (such as: creating/updating a record in the same request) and it occurs as a non-partial error. So to be in the safe side, I might handle it for both partial and non-partial errors.
CKQuotaExceeded occurs as a non partial error. I managed to reproduce that error by filling my iCloud storage by data from different apps except Photos. Backup will fill most of the storage then it won't be hard to fill in the rest of the available space.
CKUnkownItem occurs as a non-partial error when using convenience API. Also occurs as a partial error when using Batch Operation API.
All the sharing/assets related-errors, I am not familiar with them but I think the relative ones that you listed in your question, are good to be considered as partial errors.

A way of logging more info than error ID in Flurry?

I use Flurry 5.4.0 for iOS at the moment and I have a concern about being able to log more information than only an error ID when it comes to the method:
+ (void)logError:(NSString *)errorID message:(NSString *)message error:(NSError *)error;
You might wonder if I'm a bit slow, since there obviously exists a perfect parameter for just that, message:(NSString *)message. Well, unfortunately that message doesn't show up anywhere in the Flurry dashboard, which the Flurry Support Team confirmed in the answer that I got back (2014-08-30):
For error reporting, although you can pass the message in the logError function call - at the moment the dashboard doesn't have the provision to display the error message. This is something that is being considered in the long term feature road-map. Our product team is aware of this, and they would work on it, as a feature request. But, at the moment I do not have a time-line on if/when this would get implemented.
So, I don't really know how to proceed to add more important information "to" my errors. A first unsmart idea was to concatenate the information and send this in the first parameter:
errorID = errorID + errorMessage;
This to at least get the information to Flurry, but that would more or less always create unique error IDs and we would miss the great benefit of separating the errors into different kinds or errors. A really bad idea.
Apart from changing analytics provider I can't figure out a smart way to get hold of the own-created error information. Maybe I should just do that, or how do you add more useful error info to inspect at the Flurry dashboard?
Please feel free to speculate.
I asked the Flurry Team if I could get the message info from any of their ("requestable") open APIs instead and got this reply:
We do not have API that provides the error message. In addition to the errors section be sure to check the Technical -> Errors section. There is an exception log at the bottom that may provide some additional insight into the cause of your crashes.
When checking out the recommended section I found what I have been looking for. The message is located under the sub section called 'Exception Log'. I'd say that it's a bad placement, since it's more obvious to go look for logged errors under a section called 'Errors' than under 'Technical'. Right(?)
Flurry is a nice way to go so I would re frame what you define as an error and evaluate what is more important - getting the information back or getting it back as an error.
Option 1
I would log the events as some sort of sudo error (aka - "A bad thing happened" :) and use the parameters to bring back the additional details you are wanting.
Option 2
It was unclear in your response from the Flurry team if the information is completely unavailable or just not available within their portal/dashboard.
If you download the raw data from Flurry can you see the information you wanted and create your own dashboard as appropriate from that?
Hopefully this is enough speculation to get things flowing for you.

NSError code to detailed message

In my recent iOS APP I am trying to connect SSL server with past date via AFNetworking. I am getting the error "The operation couldn't be completed. (NSURLErrorDomain error -1012)". I searched apple doc and found this error mean "NSURLErrorUserCancelledAuthentication" I need to show a more detailed error message on place of this High level message (NSURLErrorDomain error -1012). How can I convert this error code to more details string message. Should I need to do this my self (check error code and then show message accordingly) or Apple provide any other good way to show this message or is there any open source category or class available for the same. Already checked
Earlier I was interested in similar thing. But could not find anything useful. I think you have to do it yourself. There is not standard mapping from Error code to detail text.
You have to write a function yourself which may return text details from an error code.
The NSError instance itself provides the most detailed messages about an error, through methods such as localizedDescription.
You've hit up against a bit of a special case though, in NSURLErrorUserCancelledAuthentication. It should only be generated in response to your code cancelling an authentication challenge. i.e. by calling completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil) or [challenge.sender cancelAuthenticationChallenge:challenge].
The framework figures that if a challenge has been cancelled, it's because the user asked to (and so there's no further UI to display), or your code chose to, and should display its own specific error info to the user.
Is there a bit of your code that is performing such a cancellation? Can you give us a bit more detail?

BroadCast Admin message to Each Session User

I have a requirement to inform every user to save their work and logout so that admin can reset iis or do some changes in the asp.net MVC application server.
looping through session object collection is not thread safe that is what i have learned.
any other ideas?
and even if i can get hold of active sessions how do i send a message to those clients ?
thanks in advance.
Save the message in a database and query the database for every request to see if a message exist.
This seems like a poorly-defined requirement.
Serious maintenance should be done at a specific time, and users should be alerted to that time window well in advance.
Simply restarting IIS is a pretty quick procedure... is there any reason users would lose their work when simply restarting IIS? While I've been filling out this StackOverflow answer, for instance, they could have restarted the server a dozen times. Once I hit Post, if the server is down, it'll either timeout and leave my work in the textarea, or else it will connect successfully if the server is back in time.
If I'm not submitting data, but just clicking a link, the same applies: either the browser times out, in which case a simple refresh is enough once the server is back up, or it eventually takes the user where they want to go.
If you're doing pure AJAX requests you will need to handle a missing server yourself, rather than relying on the browser to do it, but you'd need to work that out anyway because of the Eight Fallacies of Distributed Computing #1: "The network is reliable." (see http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing)
So, I'd actually push back on that requirement. They're asking you to do something that won't really meet the need (users don't lose data, have a reasonably good experience), that will become complicated, and that will be a brittle solution in the end.
Sounds like a case for SignalR!
https://github.com/SignalR/SignalR

Resources