Re: Returning a useful error from NSDocument's -readFromURL:...
Re: Returning a useful error from NSDocument's -readFromURL:...
- Subject: Re: Returning a useful error from NSDocument's -readFromURL:...
- From: Keith Blount <email@hidden>
- Date: Thu, 4 Mar 2010 06:44:41 -0800 (PST)
Thanks for your reply. I do appreciate it, although it is a shame that you feel the need to be so rude and spoil someone's day. I apologise if my message came across as a "ragedump and rant". I'm not quite sure why it came across that way to you, as I don't think that's what it was at all. I quoted the documentation, provided code and explained the problem I was having, and if some frustration came through that's perhaps owing to overwork on the next version of my app, so I'm sorry for that. Certainly, I made some mistaken assumptions in my previous post and didn't check enough before posting. For the record, though, I have "seriously read" the human interface guidelines. The app in question is well-respected, has thousands of users, and has been awarded four or five star reviews in every major Mac magazine in the US and UK, so please don't assume that just because someone is making a silly mistake that they are therefore a complete idiot deserving of
nothing but your scorn. We all make mistakes and bad assumptions from time to time, especially when our eyeballs have been staring at a screen for eighteen hours a day for weeks on end - if you never make mistakes then I certainly envy you.
Now, as to my problem, I had already replied just before you fired off your attack, and I have already openly admitted to being an idiot (this is nothing new, I'm sure you won't be surprised to learn). In my NSApp delegate code I had implemented -application:openFile: to do some custom handling of certain files (yes, in the proper way), and I had foolishly used [[NSAlert alertWithError:error] runModal] there rather than calling on NSDocumentViewController's -presentError: - that, of course, is why NSUserCancelledError didn't work and resulted in a blank "Error" panel. D'oh.
In my other reply I also apologised for not creating a dummy project before posting my message - that is something I should have done and I certainly deserve chastising for my oversight in that regard. You are of course right that errors work fine normally and that something in my project must be to blame - I wish I had waited until the morning and checked again rather than posting my question at the end of a long day. And, if I use NSLocalizedRecoverySuggestionErrorKey in a new Xcode project, the reason for the failure appears exactly as I wanted, in message text, beneath the bold. So the problem is that there is something else in my application that is somehow screwing up the presentation of errors, somehow causing only the localised description key to be presented to the user and nixing the recovery suggestion. As yet I have no idea what I've done in my code that could have caused this - the program has many thousands of lines in code - but it seems
to be something I've done in the version I'm working on as some more testing shows that an earlier version works fine.
Regarding the Human Interface Guidelines, I presume you mean:
http://developer.apple.com/Mac/library/documentation/UserExperience/Conceptual/AppleHIGuidelines/XHIGWindows/XHIGWindows.html#//apple_ref/doc/uid/20000961-TPXREF23
And yes, I am well aware of them, thank you. And as you can see, the HIG give three examples. The first shows a poorly written alert message, which is the title of the problem in bold. (This is what I'm getting in my app and am trying to fix.) The second shows "an improved alert message" which is still all in bold (A because of B). The third is a well-written message, which has both the bold and message text. This is what I am trying achieve, and this is how things were working until somewhere in my code things went awry. And yes, I am aware that technically the "reason" for the failure should be part of the bold message at the top, but if there is no recovery suggestion and the explanation for what has gone wrong is going to take several lines, it is better to put it in the recovery suggestion area. You could argue and say that you must abide exactly by the error definitions, but I would put user experience first in this scenario.
I really am sorry that my message provoked such bile in you, and wish you a more pleasant day than the one I am now having.
Best regards,
Keith
----- Original Message ----
From: "email@hidden" <email@hidden>
> Okay, I know this comes up a lot, but I can't find a single page with a satisfactory solution. Please feel free to post nothing but a link with the solution if I have missed the bloomin’ obvious, of course - this question has been asked here before and in other places, and it seems as though it should be simple, but nothing I try is entirely satisfactory:
No, what you're experiencing doesn't come up a lot.
> My app overrides NSDocument's -readFromURL:ofType:error: to load its data. For the different circumstances in which the load might fail, I want to present to the user an alert panel explaining the reason for the failure. This, as I understand it, is the entire purpose of NSError, except that in this circumstance it seems to be doing more harm than good and just doesn't work as it should.
>
> First, let's say I want to say to the user, "Invalid XML Data". And underneath that, in smaller, message text, I want it to say something like, "The document cannot be loaded because the XML file contained invalid characters."
You seriously need to read the human interface guidelines. There is a preferred pattern laid down for reporting errors, and this isn't it.
> So, here is my error-setting:
>
> if (outError)
> {
> NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
> [userInfo setObject:NSLocalizedString(@"Invalid XML Data", @"") forKey:NSLocalizedDescriptionKey];
> [userInfo setObject:NSLocalizedString(@"The document cannot be loaded because the XML file contained invalid characters.",nil) forKey: NSLocalizedFailureReasonErrorKey];
>
> *outError = [NSError errorWithDomain:@"" code:0 userInfo:userInfo];
> }
>
> That works okay, except that the failure reason doesn’t get displayed.
What precisely does "works okay" mean? Based on what you said above, you seem to be saying that you got an alert saying "Invalid XML Data".
However, that's not the way the standard document controller reports errors. In the simplest case, it just displays a generic message: "The document “whatever” could not be opened." If you supply a failure reason, it appends that as a second sentence. For example, moments ago I created a new project from the standard document-based application template (Xcode 3.2, Mac OS X 10.6.2), changed the "readFromData" method to readFromURL:ofType:error: and used your code to return an error. I got an alert with the following text:
"The document “whatever” could not be opened. The document cannot be loaded because the XML file contained invalid characters."
That doesn't sound like "the failure reason doesn't get displayed".
> [snip] I have tried to set outError as follows:
>
> if (outError)
> *outError = [NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil];
>
> But that results in an alert panel coming up saying nothing more than “Alert” - it still displays an error panel.
I haven't seen any indication that the standard document controller fails to handle the NSUserCancelledError correctly (that is, fails to suppress the alert).
It sure looks like there's something in your application that's superseding the normal error reporting, and doing so incorrectly. If there's truly nothing like that in your application, I'd suggest you try to recreate the the behavior you're seeing in a new, simple project that starts with the document-based application template.
> [snip]
>
> What is the correct way of handling this? It’s bad enough that the user has to see an error message at all (although on some occasions it may be used to tell the user that the project needs updating to a newer format, which is more common than genuine errors), without the error messages seeming unprofessional or unforthcoming in the information they provide. Of course, I could put all of the information into NSLocalizedDescriptionKey, but this looks horrible as it’s all in bold, and would then be one stream of text without a title. Really it should have a title telling the user succinctly that there has been an error an then some message text explaining more about the error and possibly what to do about it.
I'm sorry if it looks horrible to you "all in bold". I'm sorry if you feel the need for a "title" -- whatever that means. Seriously (on your way to seriously reading the human interface guidelines), get over it. It's to every Mac user's benefit if all applications report errors with a consistent presentation and style, and that is what the HIG are there to encourage, if not enforce.
I apologize if my response seems churlish, but your original post is basically a ragedump and a rant. Churlish is about what it deserves.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden