SKRequest didFailWithError - iphone

-(void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
}
With in this method one could arrest the error that happened for ex - ("Failed to Connect to iTunes") etc. Now if one wants to show this error message as an alert it would be really helpful for users. Like one example is when the "Failed to Connect to iTunes" error is shown as an UIAlertView, it can lead the user to the problem that his wi-fi was off all this while. He can rectify this problem and retry. But before one chooses to display these errors as UIAlertView, one must know all the possible error values that are returned because a user won't be pleased to see something like "Error %^#)$()(!)#()+! code 123_123443 blah"i.e.something incomprehensible to him. How to best handle this ? As an after thought, it would be nice to know all the possible error messages of NSError thrown in this method.
Thanks in advance

one must know all the possible error
values that are returned because a
user won't be pleased to see something
like "Error %^#)$()(!)#()+! code
123_123443 blah"i.e.something
incomprehensible to him
I don't know all the possible errors that particular method can return but I think it is safe enough to use the localizedDescription method of NSError to present the error to the user.
From Apple docs:
Error objects in the Cocoa domain are
always localized and ready to present
to users, so they can often be
presented without further evaluation.

Related

What delegate method is called when an ASI-HTTP-Request times out?

I have an app that uses ASI-HTTP-Request for large files, and I had a tester recently note that they wer observing very long loading delays that should be manifesting as timeouts. I have delegate methods wired up for request failures, but these didn't seem to be happening.
I poured through their documentation but didn't see anything specific.
In ASIHTTPRequest.m, look in the -checkRequestStatus method.
When a timeout occurs, the request fails with an ASIRequestTimedOutError error type:
[self failWithError:ASIRequestTimedOutError];
So you should be able to check the error returned in the delegate's -requestFailed: method:
- (void)requestFailed:(ASIHTTPRequest *)request {
NSLog(#"Error: %#",[[request error] localizedDescription]);
}
It's a good idea to read through the source to get a rough feel for how things work. The documentation is great, but not always in sync with the source code.

iPhone Production/Release Exception Handling

In advance, please excuse my lack of understanding for iPhone/Objective-C Best Practices; I come from a .NET/C# background.
Although, I've read many posts regarding exception handling for the iPhone, I'm still not exactly clear on what most people do for production code. Also, I haven't been able to find any open source apps with error handling that I would normally expect. Here are my questions:
1) If an unexpected result occurs that would cause the application to eventually fail, would you throw an exception or just wait for it to fail later? For example,
if (![fileManager createDirectoryAtPath: myNewDir
withIntermediateDirectories: YES
attributes: nil
error: &myError]) {
// My app shouldn't continue. Should I raise an exception?
// Or should I just log it and then wait for it to crash later?
}
2) Do you validate parameters? For example, in C# I would usually check for null, and if needed throw an ArgumentNullException.
3) When an app crashes, does the crash info get logged automatically or do I need to set the unhandled exception handler? Can I show a UIAlertView within this method to inform the user something bad happened, instead of having the app just disappear? (If so, I couldn't get it to work.)
4) And finally, why don't I see anyone actually using #try/#catch/#finally? It's used extensively in C#, but I haven't found open source apps using it. (Maybe I'm just looking at the wrong apps.)
Ad 1. The example you give is a somewhat classical example of when one should use a "checked exception" in Java. The caller of the method has to be prepared, that the call can fail for reasons which are outside of what it can control. In particular, in the example given, I would allow the error descriptor object allow to propagate back to the caller:
- (BOOL) prepareDirectories: (NSString*) path error: (NSError**) location {
if( ![fileManager createDirectoryAtPath: path
withIntermediateDirectories: YES
attributes: nil
error: location] ) {
return NO;
}
// ... additional set-up here
return YES;
}
If the error is really not recoverable, you may actually raise an exception, but that will also forfeit any chance to show a proper error message to the user of your application.
Ad 2. Yes, parameter validation is definitely something you should do. And raising an exception for unexpected nils is entirely appropriate. A bad parameter is a "programmer's error" and you cannot guarantee, that the program is still in a consistent state. For example, NSArray raises an exception, if you try to get an element using an non-existent index.
Ad 3. When the app crashes due to an uncaught exception, the fact is logged automatically. You can catch the exception if you really want to display an error message. However, the app is likely to be in an inconsistent state, and should not be allowed to continue, so simply allowing it to go down seems the best solution here.
Ad 4. I don't know.
In the specific case you mention, you should present a notification to the user about what just happened with instructions on how to fix the situation. Except in extreme circumstances your app should not quit. You should let the user fix whatever is wrong, then try again.
Parameter validation depends on a lot of factors. One thing to keep in mind is that in Obj-C it's perfectly valid to send messages to nil (nothing happens if you do) so in a lot of situations you don't need to check for nil. If I'm in a model class I always validate parameters in methods. If I'm not I almost never validate anything, type checking is good enough.
Some information should be logged but it's always helpful to log more specific information to your situation. Ideally you shouldn't ever reach the unhandled exception state.
Cocoa classes will rarely throw exceptions for environmental reasons, they are almost always because you did something wrong. For example, you wouldn't usually put a #try/#catch block around [NSString stringWithString:] because the only way it'll throw an exception is if you try and pass nil. Make sure you aren't passing nil and you won't have to worry about catching exceptions. When a method might fail because of something outside of your control, they usually communicate via an NSError. See the - (BOOL)save:(NSError **)error method of NSManagedObjectContext for example.

How to properly handle Core Data save errors wrt user experience on iPhone?

So, I have a basic app for storing, searching, and manipulating data. Basic CRUD operations. In various places of my code where I'm storing or updating this data, I basically have this:
NSError *error;
if (![self.managedObjectContext save:&error]) {
// TODO: Handle this error
NSLog(#"Error while saving data %#, %#", error, [error userInfo]);
}
What do most people do, user-experience-wise, when these sorts of things come up?
The only thing that comes to mind is to just pop up some horrible UIAlertView with a vague message that something went wrong; not really sure how to recover these things.
For the sake of argument, lets assume my model has little to no validations, so the only errors that might occur would either be something horribly wrong or a programming problem.
Any good ideas on the user experience?
Jakob Nielsen has a few concise guidelines you might want to check out; out of everything he proposes, the one I strongly suggest you indicate in an error message that it's not the user's fault. From my own experience in user testing, most users believe they did something wrong when an error pops up, and this leads to frustration.
Maybe something like:
There was a problem saving: don't worry it's not your fault! If you restart the app, you can try again. But please contact [developer contact] and tell him the error was [short, memorable error code]
In a case like this, I think the best thing to do would be to present an alert to the user and quit the app.
Short answer is that I have never had a save error occur in production. Normally I make these asserts and have them crash the app. This is to make sure I catch them during development.
If your application is well-written you should not have one of these occur when a user is running the application.
As for the text, it depends on your application and there is no general rule for them.

iphone error dialog?

I wonder if is possible display a dialgo when a unexpected error happend in the iPhone (and not quit blindy the app!) and have time to log or send by email the crash...
Yes. For starts implement NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler) and then use something like Crash Reporter. Good stuff.
I don't know if you can show a dialog, but you can probably do some logging by specifying a top-level exception handler using the function NSSetUncaughtExceptionHandler
I remember there being a method you could override in your application delegate class that would be called in the event of an unhandled exception. A few days ago someone wrote a blog post where they shipped off the exception information to a web service from that method.
I apologize that I can neither find the name of the method in the UIApplicationDelegate protocol or the blog post I saw the other day. Apple's online documentation seems to be un-searchable at the moment (grrr!) and I cannot remember where I saw that blog post - if I find it, I'll edit this post to include a link to it.
But it may be possible to have some sort of recovery, or at least the ability to store off error information to disk so it can be sent later.

Mac OSX/iPhone error handling in the App Delegate?

I'm curious, how do most of you folks handle errors such as HTTP Forbidden or 5xx type requests from a server? Or say an exception is thrown in one of your UIViewControllers? Do you typically bubble up the error to the App Delegate and handle generic "window" level errors at that point? Do you couple errors directly into the UIViewController? What if you have several UIViewController's which all speak to a common NSURLConnection wrapper, and a connection fails for some HTTP 4xx or HTTP 5xx similar error. Will you typically bubble up the error to App Delegate so it can present a UIAlertView from that portion of the application?
Just wondering what solution you're using for your Mac OSX/iPhone error handling techniques.
Thanks a bunch.
Your current view controller should be responsible for dispatching any error message and dealing with the result.
The last part is the key here. If you encounter an HTTP error and pass the message up to your app delegate with a "retry" option the response then needs to go all the way back down to the controller. This all gets a bit yucky.
Now you may want to create a common class/view in your app that can deal with all the errors you're likely to encounter, but this should still be presented (in a modal fashion) by the controller that encounters the error and it's this controller that should receive delegated responses.
The controllers may or may not need to know there has been an error in order to properly recover from a network error, but for iPhone development I have found it useful to have a core communications class that understands all the communication going into and out of the system, and when it detects failures issues an alert directly. That way you can prevent an overload of failure notices if a user switches tabs or otherwise moves about the application, and just generate one message so that the user can understand why screens are not updating.