You need to signal success or failure of a request to its sender.
The sender is a human
user. Humans hate being told what they did was wrong, and if your application does it then they will start hating it. Humans also hate being interrupted and told what to do, especially when either or both are gratuitous.
Failure is a normal part of life. Human beings do not appreciate, like, or react well to negative reinforcement.
Use positive reinforcement exclusively. When the request is successful, signal it with either its result, or some pleasing soundbite. When the request is unsuccessful, signal it with either silence, or a result that doesn't interrupt the user's work flow. Be noisy with success, unobtrusive with failure.
Example 1: What you get when you fetch a WikiPage
or web page that doesn't exist. (i.e. a web page that says "this page doesn't exist, try looking here", not
a beeping "file not found" pop-up message box)
Example 2: The Transmission Stopped! message at the end of a web page when you stop OperaBrowser
from fetching it. (not
complete destruction of whatever has been transferred so far, or a modal dialog that refuses to proceed until the user confirms that the web page is incomplete)
Netscape used to do this too. I don't remember what the exact message was, but the first character was >, to close any HTML tags that might have been open.
Criticism and contradictions with well-established practices:
"Human beings do not appreciate, like, or react well to negative reinforcement."
Strongly disagree with the 'react well' part. Many people react far better to negative criticism than praise. In the military they beat you down with verbal abuse and many perform far better under that environment than if they were coddled.
suggests that if you have nothing surprising to say, don't say anything. Success should not be surprising. ThereIsMoreThanOneWayToScrewItUp
- given a lack of CosmicAwareness?
it is impossible to predict all
failures ever. There are also contexts in which you can't lock down all potential failures. A good example is trying to match against the Postcode Address File (PAF). There are too many types of failure to not
tell the user precisely why you couldn't do what they asked, many of which you can't pre-empt. There are even cases where you explicitly need to allow
- many of which you can't pre-empt.
While I agree with many of the ideas on NewOsFeatures
(which I belive spawned this page), I can't disagree more with this one. Perhaps I've just used un*x for too long and have had my brain warped, but I prefer the exact opposite of this idea. I'd even go so far as to say the first line of the page is an flat-out lie. Silent failure isn't the inversion of an AntiPattern
, it's an AntiPattern
I tend to get really annoyed at noisy success. It irks me when some simple CommandLine
program feels the need to spout *useless* messages all over my terminal. It's even more irritating in a GUI. Success is (or should be) the norm. Being noisy about it interrupts my workflow.
On the other tentacle, silent failure is even worse. If something is wrong, I want to know what. While MakeFailureImpossible
is a lofty goal, it is also impossible in many (most?) cases. In such a case, I would vastly prefer to know what's going on. (This isn't to say that I want an application locking modal dialog, that's annoying too.)
Basically, I want the computer to do what I tell it to. And be quiet about it. If for whatever reason it can't do what I want, tell me. Simple as that. -- LeviAho?
Silent failure can leave people waiting indefinitely. Is it done? Did it work? It hasn't said anything for 10 minutes. I guess I'll wait another 10 minutes. How will I know when to stop waiting?
When it's not "finished" but also no longer "in progress". Both of these stages are successful stages, not failures. The only reason you'd need to signal failure is if you never signaled completion or progress in the first place.
Another example, when Linux boots up it displays a whole list of gratuitous progress information. That information has no meaning to most users, it's just Linux' way of repeatedly screaming Success! Success! Success! If Linux suddenly stops scrolling all of that progress information, the user immediately knows that something's wrong.
- I'm confused. How can it not be finished if it is no longer in progress? And why is that a successful stage? How will it signal completion or progress if it fails silently?
- Finished is a successful stage. In progress is a successful stage. When it's neither then it's a failure. And you don't need to signal that failure with anything but silence because the user is already accustomed to both finished success and progress success.
- Noise indicates progress or completion. Silence indicates either failure or no request made. The user can figure out whether it's failure or no request from their own memory. The worst-case scenario is the user doesn't remember and has to repeat the request. And in most cases that's less annoying than noisy failure. And if the request takes all day, then you can bet your ass the user remembers whether or not it was made!
- When Opera queues a connection, a grey bar appears at the bottom of the window with "Connection request queued" at its right corner and a timer starts ticking from 0:00 in its middle. When it proceeds to different progress stages (name lookup, receiving) it indicates this in the same manner. When it's finished, the page has been displayed in the main window. So all stages and types of success are displayed. The absence of all of these (no progress bar and an empty window) means failure. It's unambiguous.
Contrast that with MS Windows which explicitly lays the blame on you for not shutting down properly after it crashes. That kind of selfish arrogance is the result when you start believing you have a mission to "instruct" or "educate" the user (the most common justification for error dialogs). Which in turn is the result of being tightfisted with progress/success information because you believe the user is too stupid to understand it.
Which leads back to the point made by AlanCooper; do you want to cooperate with users even at the price of catering to their psychological needs, or do you prefer to wage war against them?
- Only if the user knows to expect success information within a certain amount of time. Otherwise the user is left to wonder when the next message will come.
- Users aren't stupid. They only start to "wonder" if you go out of your way, like MS Windows, to insulate them from feedback. If you make sure to provide them with constant feedback all of the time then they'll have nothing to wonder about.
- I don't want constant feedback. I'm doing other things. I want to be interrupted on failure or success. I want to poll for progress.
- Constant vs intermittent feedback is orthogonal to polling vs interrupts. You can have constant feedback in a window which you're not forced to pay attention to, or intermittent feedback in a window which you're forced to pay attention to (eg. an error dialog). Constant feedback doesn't mean constant interruption.
- The problem with your claim that you want intermittent interrupts is that most people hate all interrupts and it's an empirical fact that forcing humans to multitask leads to gross inefficiencies. Besides, most of the time "interrupts" aren't even important and it's only the arrogance of the application programmer that leads to classifying them as interrupts. So "interrupts" should always be queued and presented only when the user polls for them. If the user explicitly chooses to receive interrupts then that's another matter. The point here is that it's the user, and not the programmer, who must choose whether or not to receive interrupts.
- So we have here something we may call the Interrupt Problem. How does the user signal / program their desire to receive or suppress certain kinds of interrupts? But there's already a solution to the Interrupt Problem in the case of CLIs. In bash, you can redirect any error output to a file or /dev/null. Naturally you can't do that in GUIs, anymore than you can do piping, scripting or anything else, because programmers are either too lazy to implement features already found in CLIs or too arrogant to provide useful functionality to mere users.
I just want to let them know when I couldn't do what they asked.
Why? This is a serious question. Is there something they can do to change the fact that you couldn't complete their request? Or is it impossible to fulfill their request and it was your fault, your laziness, that you made it appear to them as though it was possible?
The only case when an "error" might be justified is if the request was possible to complete but became impossible after it was made. Like writing to a remote file that got deleted after the write request was sent over the network. But this isn't an exceptional situation deserving of special attention so it's not an excuse for the software to start whining. All it means is you go back and change the status of the request from possible to impossible; you grey out the icon, you disappear the filename, you change back the colour of the form from green for Go to whatever it was before.
- Sometimes there is something I can do to help the computer complete the request. Insert a floppy, for instance. I'm not sure who "you" means regarding laziness. The computer? The programmer?
- Yup, the lazy-ass programmer. For instance, if your request can't be filled without inserting a floppy first then it was impossible to fill in the first place. The software shouldn't have portrayed the request as possible. OTOH, if the software requires some kind of interaction with the user in the middle of a task, then the programmer shouldn't have been so stupid as to consider the whole task to be a single request. Rather, there's Stage 1 upon whose completion you move on to Stage 2 and so on. The days of "Insert Disk #2 to continue" are long gone.
- So the floppy drive icon shouldn't appear anywhere unless there's a floppy disk in the drive? How will the user know the computer knows it has a floppy drive and what it's called?
- If there is a floppy drive then there should be a greyed out, translucent or somesuch icon. When you put in a floppy, it becomes a normal drive icon. But until you put a floppy in, it should be impossible to even try to "go to" the floppy's contents. This really isn't rocket science.
Let's take another look at OperaBrowser
. When a connection times out, there's usually something I can do. Usually, it times out because my dialup connection screws up. So what I can do is reconnect to the ISP and reload the page. So it actually makes sense for Opera to signal failure in some way. Or does it?
The majority of the time that I get connection time outs is because I'm not connected to the net at all. Can I do anything about the time outs? No. Do I want to do anything about them? No! So why the bloody hell is Opera tearing my attention away from the page I'm reading in order to whine to me that some connection I don't care about is timed out? In fact, even when I do want to reload the page, popping up an error dialog to tear my attention away from what I'm doing is a BadThing. The time outs should accumulate unobtrusively in their own little window, exactly like Opera's transfers window accumulates file downloads. This would communicate them to the user
when the user wants to see them and it would gather them all in one place where they can't be lost. And the reason for this is because time outs are not errors, they aren't "exceptional situations which justify the special attention of the user".
Why is it considered acceptable, even virtuous, for application software to be whiny?
From above: So the floppy drive icon shouldn't appear anywhere unless there's a floppy disk in the drive?
(I don't know about MacOsx
) this is exactly how it worked - if a disk of any kind (logical or physical) was available to be used, it would appear on the desktop. I found it perfectly natural to use - no floppy visible, the drive is empty. In comparison, whenever I used MicrosoftWindows
, I would find it annoying to see the icon representing the floppy drive in "My Computer", because I could click on the icon, only to be rewarded with an annoying dialog box saying the drive was empty.
How will the user know the computer knows it has a floppy drive and what it's called?
The user has to assume at least minimal competence on the part of the people who programmed the OperatingSystem
. Speaking as someone who has suffered through installing LinuxOs
numerous times, I would really, really like to be able to assume this. But often, sadly, you can't. -- EarleMartin
Discussion (moved from NewOsFeatures)
[One of the suggested NewOsFeatures] seems to be suggesting that silent failure is a good thing, which seems obviously wrong.
Web browsers use silent failure because this is considered a good thing in GUIs. Personally, I can't stand when OperaBrowser
opens an error dialog just because a connection timed out. It should treat connection time outs just like stops by displaying a valid-seeming page with Transmission Stopped! at the end. See InteractionDesign
for more details.
Sorry, I'm not convinced. It sounds to me like this is something that should be user-configurable. I do not consider it a feature that silent failure behavior should be imposed upon me by the OS designer.
- [That's not silent failure, that's just a more graceful way of signaling failure than a pop-up dialog box. If it were failing silently, it wouldn't bother to tell you "Transmission Stopped!", rather the page would just end at some point or you'd see a blank page with no clue as to why there isn't any more.]
- There are plenty of examples of silent failure in Opera's page rendering. If you're not satisfied with that particular example then replace it with another one. For example, my dialup connection program uses only silent failure. I'd be very surprised at any that didn't.
- I prefer to lump things into silent failure rather than to nitpick between Graceful Failure, Humble Failure or simply No Failure. I suppose it was stupid of me to presume that people would absorb the central message of this page without nitpicking between absolute silence and relative quiet. The status quo is noisy failure, quiet success. The point of the page is to do the exact opposite. Whether quiet means silence, grace, humility or non-existence never seemed important to me.
- [May I suggest then avoiding the term "silent", as it seems to be giving the wrong impression to many of the people who have commented here.]
Silent failure is just intelligent design.
So far you have not supported this generalization. I am arguing that whether you prefer silent failure or noisy failure is a subjective matter. Claiming that silent failure is inherently more intelligent design than noisy failure is just dogma.
An OS forcing noisy success is no more undesirable than a language forcing OO programming. That's because when failure is as common as waves in the ocean, its exact nature is rarely of relevance. And when you allow users to formulate invalid requests, you get a flood of failures. The lesson is to MakeFailureImpossible
- In other words, make it impossible for the user to do anything interesting?
If the scheduler complains every time a user creates a process with no text, data or stack, or the window manager complains every time a user creates a window without any dimension, then you've got a whiny bitch of an OS.
- If the documented behavior of the OS in response to these situations is to be a whiny bitch, then it is the responsibility of the programmer to cope.
And stupid besides since the proper responses to such "errors" are obvious. The scheduler need only suspend the process until text and stack are created, the window manager need only create a window of zero dimension.
- In other words, the documented behavior of the OS in response to these situations should not be whiny bitching. This has nothing to do with silent or noisy failure. This is not failure at all. It's simply a matter of designing the API well.
- You mean it's not a failure when the scheduler can't load a process because it's malformed? In that case, what could possibly count as failure to you?
Going in the other direction, if the text editor can't modify a document then it shouldn't allow the user to modify it. And if it can't write to some directory then it shouldn't display it to the user at all. That's only the tip of the iceberg because there's no limit to the extent you can treat errors and fuckups as just very strange but entirely valid behaviour.
That assumes the editor knows where the user wants to save the document before it opens the document. The user may not even know that. How will the editor?
Hardly. It merely assumes the editor doesn't open a Save As dialog which displays every directory whether it's writeable or non-writeable by the user. All that's required of the editor is that its dialogs display only valid possibilities.
Besides, in an OS with TransparentPersistence
(the kind described in NewOsFeatures
, where this thread originated) the entire operation of "saving" a document is meaningless and the editor always
knows where to "save" a document before it opens it (or it would, if the operation weren't meaningless).
I don't like silent failure. I see it too often. Just last week we had two new PCs that popped up a window when we powered them up, saying "initializing something or other, please don't touch keyboard or mouse...". We sat there for 20 minutes wondering if they were initializing or if they had failed to initialize. Eventually we gave up, but there was no stimulus to prompt that action. We did it because we guessed. I don't want to guess. I want to know.
In the example above, it's not silent failure that caused the problem but silent success. If you were used to software that gave constant progress updates, you would have known immediately that it had failed to initialize precisely
because it was silent.
If it stopped giving constant progress updates, how long would I have to wait to know that? What if it was the first time I used it?
Then too bad. It's completely unreasonable to design user interfaces to the stupidest, most ignorant, or least experienced user imaginable.
. [Now, that's what I would call arrogance]
I'm glad you don't design my user interfaces.
On the one hand, you don't want to cut off too many people. On the other hand, if you've got 10,000 users, and you design for the 10,000'th guy on the competence list, that's at least 9,900 users you're going to end up alienating. If nothing else, Mr(s). 10,000 needs something on the screen to report to Mr(s). 500 when they go looking for help. It is neither arrogant nor unreasonable to say that you can't design interfaces to the bottom .01% and expect a useful program for most people to emerge; it's the exact same error, in reverse, as designing for the top .01%.
Let's imagine this pattern applied to a compiler. On success it prints "Compilation succeeded." On failure it prints nothing. How do I know what caused it to fail? -- EricHodges
last 20 progress.log
Except that the compiler, being designed intelligently to display its successes (progress) noisily will have displayed it all in its window. So just glancing at it will show the last functions successfully compiled and the last operations attempted. At that point, knowing the operation which the compiler failed to complete should enable any cretin to put two and two together to figure out where it failed. Answer: it failed in the last operation it attempted.
Perhaps you can take this opportunity to justify your belief, made implicit numerous times on this page, that user interface design should be targeted at people at least 20 IQ points below the stupidest of computer literate users.
Isn't it better to show ONE failure message instead of 100 success messages. I tend to get lost in a sea of messages.
No. If you don't want to be swamped by a mass of details then you can stick to displaying "working .../-\|*" to indicate that the program is working on whatever. Then, when it fails it should display the failure point in the exact same mode as it's been displaying progress. So there are no modes, no error dialogs, no beeps, no annoying stuff.
3rd voice: For a compiler, "success" includes printing diagnostics about the input file and exiting with a non-zero code when the input is incorrect. Thus, it noisily succeeds by printing error messages!.
And in that vein, FreedomIsSlavery.
As a compiler user, I don't care what the compiler programmer thinks is success or failure. The programmer is there to cater to MY needs and so I get to decide what's success and failure. And if the compiler crashes then woe be to the compiler writer! And if the OS displays an error message because the compiler crashed then woe be to the OS writers!
It seems that most of this dialog could be summarized by:
"But ... things *do* fail. The user *needs* to know there's a problem. If the software does *nothing*, is *silent*, the user is left in suspense as to whether the computer is still working on it, or if there is some sort of failure. You must *indicate* failure somehow."
"Yes, if you simply silence programs that currently have noisy failure, keeping the user in suspense is a problem. But when it comes to fixing that problem, ThereIsMoreThanOneWayToDoIt
. Rather than make failure noisy, I prefer to make success more noisy. If there's some little animated thingy that keeps spinning while the software is *working*, then when that stops, the user knows it is *done*. For example, a compiler could write out the function name and line number it has *succeeded* in compiling, then overwrite it with the next function name and line number it has *succeeded* in compiling. When the compiler can't understand some line, it simply stops. If the user turns sound effects on, he hears faint 'crunching away' sounds (positive) as the compiler works, then either dead silence (failure) or some happy trumpet fanfare."
On the AppleMacintosh
, dragging a song from AppleItunes?
(iTunes) to a track in GarageBand
: I drag the song over the track region in GarageBand
, and a Plus icon appears to indicate that dropping is possible. So far, this matches the behavior described in the manual and in help. Next, drop the song - nothing happens. This is a silent failure.
This particular behavior follows the rule of SilentFailureNoisySuccess
rule, but badly breaks the rule of discoverability. To discover the cause of the failure, I had to dream up experiments. Try dragging another song - does that work? No. Try dragging another song - does that work? Yes. Ok, so the icon wasn't totally lying - it is possible to drag a song to a track. OK, why not the song I wanted - oh, I see - the songs that won't drop have longer names. I guess there's some kind of maximum name length limit in GarageBand
tracks. Nice of it to tell me that in the first damn place!
Now, that doesn't mean obtrusive failures that interfere with the work flow are good, but simple silent failure is not a better answer.
Oh really? It seems to me that your problems are that your Mac
lied to you and that the application you're using is retarded. If the only counter-argument that people can come up with against silent failure is that they have to deal with retarded software, then it's a damned good argument for instituting universal silent failure ASAP. Broken software will be totally intolerable and people will no longer put up with that shit. -- RK
Every program has faults, and no program is ever finished. If one of the programs infrastructure decisions (in this case, silent failures) makes those minor faults into serious impediments to use, to me, that's a much bigger problem than the faults themselves. I'm envisioning being the programmer looking at the bug database seeing "Minor - Can't drop files with very long names" next to something like "Major - crashes with more than 9 tracks on OS X rev xxx". Which one do you think will get the priority fix for next release? How mach programmer time would have to be dedicated per release to -ever- get that minor bug fixed? How much would the product cost? If features are scaled back to fix minor bugs and keep costs down, will the product compete with other products' new features?
Now, add to that the fact that there are possible compromises between the extremes of modal failure dialogs and utterly silent failure...
I'm sorry but I do NOT consider being unable to deal with long filenames to be a minor problem. I consider it to be a critical problem, one indicative of a major and fundamental architectural fault in the software. This is the kind of thing that programmers should get fired over.
As for dealing with more than 9 tracks? I consider trying to deal with more than 1 track to be a serious misdesign of software. But then, that's because I actually understand that sequencing objects (songs, movies, whatever) is a completely independent function from operating on those objects. In fact, sequencing is a basic operating systems function. And even admitting the fact that mainstream OSes are so retarded that they don't provide this function (though Unix does provide it in the shell), the fact would still remain that you're dealing with two radically different and wholly independent pieces of software and so trying to compare bugs between them is just plain dumb.
Finally, it's just like a programmer to buy into the idiot myth that "features" give value to software. They do not. What gives value to software is giving the user the ability to consistently and uniformly perform a few very simple and basic operations. Users don't give a damn about "playing mp3s" vs "playing avis". They care about "playing a song" or "playing a movie". Stick to one basic operation and perform it consistently (eg, regardless of input stream format) and for the love of my sanity, do NOT get lost in the idiocy of "features". Especially "new features" introduced by your competitors, who are invariably idiots anyways. (I mean geez, do you really think you can get a competitive advantage doing what every other moron is doing??) In other words, to the question "is it better to fix minor bugs or introduce new features", I say to hell with the features!
I'm against silent failure and recently had a case come up where it was potentially a life-or-death issue. I'm working on a mapping component for an open-source project that helps operators co-ordinate disaster rescue teams. The lead developer is of the opinion that SilentFailure?
is good, i.e. it is better to have a broken map than no map at all, and that errors should therefore be ignored. Consequently, if a map layer or feature fails for any reason, the map still shows, without the feature, and without any distracting warnings. Now imagine that those map features represent people on top of buildings in a flood, about to be swept away and drowned, who have 'phoned in their positions. Some minor website configuration problem means they don't show up on the map. The helicopter won't rescue them because the operator won't know they are there. They would be swept away and lives lost. It is obvious to me that it is far better that the operator is told that there is a problem and that the map data is misleading, at least then a helicopter could make a pass over the area. Despite this argument, which I presented to him, the lead developer still believes that missing a.k.a. misleading data is better than no data and wants to keep all the do-nothing catch blocks in the code. I'm dreading the day arrives when I have to tell him "I told you so". Is this negligence? I write this code but not in a way I want. Could I potentially get sued if this did happen?
LimpVersusDie is a different issue than SilentFailureNoisySuccess. For example, you could provide an icon to indicate when a layer is not displaying correctly, or that you're using cached information, and still provide a partial map.
It strikes me that the best approach is to do whatever's quietest while still allowing the use to know what they need to know - I don't think anyone's arguing that a compiler should pop up a new dialog every time it tokenises another method, and I don't think anyone would object to having the system-tray icon change from yellow (changed or compiling) to red (failed) or green (succeeded) provided you could then go and find out more about the failure (whether that's a list of the tasks that were started, or a detailed error condition report is, in many ways, unimportant).
Both sides of the argument seem to have been spending a lot of time chasing scarecrows, or arguing about issues orthogonal to the page's topic...