Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I was under the impression that by now everyone agrees this maxim was a mistake. But I recently saw this answer which has a "be lenient" comment upvoted 137 times (as of today).

In my opinion, the leniency in what browsers accept was the direct cause of the utter mess that HTML and some other web standards were a few years ago, and have only recently begun to properly crystallize out of that mess. The way I see it, being lenient in what you accept will lead to this.

The second part of the maxim is "discard faulty input silently, without returning an error message unless this is required by the specification", and this feels borderline offensive. Any programmer who has banged their head on the wall when something fails silently will know what I mean.

So, am I completely wrong about this? Should my program be lenient in what it accepts and swallow errors silently? Or am I mis-interpreting what this is supposed to mean?


The original question said "program", and I take everyone's point about that. It can make sense for programs to be lenient. What I really meant, however, is APIs: interfaces exposed to other programs, rather than people. HTTP is an example. The protocol is an interface that only other programs use. People never directly provide the dates that go into headers like "If-Modified-Since".

So, the question is: should the server implementing a standard be lenient and allow dates in several other formats, in addition to the one that's actually required by the standard? I believe the "be lenient" is supposed to apply to this situation, rather than human interfaces.

If the server is lenient, it might seem like an overall improvement, but I think in practice it only leads to client implementations that end up relying on the leniency and thus failing to work with another server that's lenient in slightly different ways.

So, should a server exposing some API be lenient or is that a very bad idea?


Now onto lenient handling of user input. Consider YouTrack (a bug tracking software). It uses a language for text entry that is reminiscent of Markdown. Except that it's "lenient". For example, writing

- foo
- bar
- baz

is not a documented way of creating a bulleted list, and yet it worked. Consequently, it ended up being used a lot throughout our internal bugtracker. Next version comes out, and this lenient feature starts working slightly differently, breaking a bunch of lists that (mis)used this (non)feature. The documented way to create bulleted lists still works, of course.

So, should my software be lenient in what user inputs it accepts?

share|improve this question

migrated from stackoverflow.com Jun 12 '12 at 13:55

This question came from our site for professional and enthusiast programmers.

4  
Regarding "discard faulty input silently," I'd ask for each case what should be considered as faulty input. If you ask a user a question and expect "yes" or "no", is "YES" faulty input? How about "y"? How about "oui"? In general, don't be shy about telling the user that their input isn't what you expect. However make sure you've been as inclusive as possible -- in my mind, that's what's meant by "be lenient". –  Tenner Jun 12 '12 at 13:38
3  
If you are talking about end user input - which relates to the user friendlines of your application, then you should be leinent; for automated machine generated input (from an API), you should be verbose (strict). –  Burhan Khalid Jun 12 '12 at 14:13
2  
Actually the leniency of HTML was why it became so popular (and the strictness of XHTML why it was dropped). –  Oliver Weiler Jun 12 '12 at 14:49
1  
I think the key is that if it is a scenario where you can allow it to fail gracefully is that you at the very least log the event. –  Rig Jun 12 '12 at 18:31
1  
@OliverWeiler I feel XHTML's failure had something to do with the fact that it was entirely unneeded. HTML was already there and kinda worked. Also, while HTML is of course immensely popular, it's kind of sad that we're calling this technology a success. It satisfies the demand, but it does so about as well as Symbian satisfied the demand for smartphones. –  romkyns Jun 12 '12 at 21:05

11 Answers 11

up vote 7 down vote accepted

Of course you are completely right. Programs should never be “lenient” as doing so only serves to mask problems. Problems should be highlighted, not swept under the rug. An informative error message is an absolute must for a program to be helpful to the user.

Most of the time when incorrect/invalid data is provided, the provider of that data (whether it’s a user or the output of some other program) probably didn’t know it was invalid. Swallowing the error will keep them in the belief that it is (or might be) valid, which proliferates invalid data.

The only way for systems to interoperate is for that interoperation to be fully and unambiguously defined. A program that accepts data outside the specification makes that data de facto accepted even if it is invalid by the spec, which not only makes compatibility a huge load harder, but also means it is no longer formally defined. The program itself is now the de facto standard. Thus, lenient programs are impossible to develop further or to replace because you can’t make the minutest change to how it operates.

share|improve this answer

I think that it all depends on who your target demographic is. If it's programmers, then absolutely not. Your program should fail hard and scream bloody murder. However, if your target audience isn't programmers, then your program should be lenient where it can handle exceptions gracefully, otherwise, whisper sweet bloody murder.

As a case study, take the NPAPI Flash player. There is a "release" version for those who don't really care about 99% of errors that can occur, but there's also a "debug" version that can be used that screams bloody murder when anything goes wrong. Each support playing Flash content obviously, but are targetted to two completely different demographics.

In the end, I think that the important thing is: What do your users care about?

share|improve this answer
3  
The vast majority of Unixy command-line tools that claim to have a target audience outside of programmers are nonetheless useless to users who make mistakes. Even if you are not a programmer, it is usually better for a program to explain a problem than to do something nonsensical or unintended. –  Timwi Jun 12 '12 at 14:08
2  
@romkyns: Not completely, I'm saying that your application should handle errors in ways that make sense for your targeted users. –  Demian Brecht Jun 12 '12 at 14:19
    
@Timwi: In which case, those Unixy command-line tools are poorly architected ;) –  Demian Brecht Jun 12 '12 at 14:20
3  
@romkyns - I think a good example would be: In debug mode, you want a program to stop on any problems and tell you what went wrong. In production mode you want your program to continue working as well as it can, and log any problems it can handle. This way, programmers can see what they did wrong and fix it, but users won't be bothered with things they can't fix. Some problems obviously can't be fixed, but a good example is CSS style rules, where you can still render a site, even if you don't understand one of the style rules. –  Brendan Long Jun 12 '12 at 15:30
1  
@BrendanLong's comment pretty much hits the nail on the head - sometimes producing output is more important than being correct. Some errors (or warnings) can be gracefully recovered from, without input from the user; it's up to you to decide what you want your application to do in these cases. –  Daniel B Jun 13 '12 at 6:25

There's two types of "lenient": One is to accept incorrect input and try to make sense of it, and the other is to accept different types of input.

Generally, you always want the second one when it's feasible. The first one is when you die fast and hard. An example: Dates.

Here're some example inputs, including valid, invalid, and ambiguous.

  • 2011-01-02
  • 01/02/2011
  • Jan 2, 2011
  • 2-Jan-2011
  • Green

There's only one invalid input here: Green. Don't even try to accept it as a date. Since Green is obviously not a date, this is a case where silent failing is acceptable.

01/02/2011 is valid, but ambiguous. You don't necessarily know whether or not it's been entered as a US date (Jan 2) or not (Feb 1). Here, it's probably best to fail loudly, and ask the user for an unambiguous date.

2011-01-02 is usually considered unambiguous, so it's often fine to go ahead and assume it's the format "YYYY-MM-DD", and only fail further down the line. It's a bit of a judgment call, though, when dealing with user input.

Jan 2, 2011 and 2-Jan-2011 are valid and unambiguous, they should be accepted. However, The Second of January of the year 2011 is also valid and unambiguous, but going that far for the sake of leniency is overkill. Go ahead and fail it silently, just like Green.

In short, the answer is "it depends". Take a look at what can be inputted, and make sure you're never accepting conflicting types of input (like DD/MM/YYYY vs MM/DD/YYYY).

In the context of the linked question/comment, That is a case of 2011-01-02. The input looks like JSON and will validate like JSON even if the mimetype is wrong; go ahead and try to use it even if it fails at some point further down the line.

share|improve this answer
    
There's one thing you're not considering here. If the user typed that string then yeah, I should accept various formats, no doubt about that. But we're talking of APIs. APIs' clients are other programs. If it's lenient in its date format, every future server exposing this API will have to be lenient in exactly the same way or risk incompatibility. The leniency ends up being detrimental rather than helpful, don't you think? –  romkyns Jun 13 '12 at 12:58
1  
@romkyns I think you're misunderstanding where the leniency lies. The API should be lenient in what it accepts (it should understand all of 2011-01-02, Jan 2, 2011, and 2-Jan-2011, if it's not too difficult to implement), not in what it outputs. Future clients to that API don't even need to know about any given one, as long as they're correctly inputting one of them. Ideally, the API layer would convert all of these to the same internal representation that the code uses before passing it along. –  Izkata Jun 13 '12 at 14:06
    
@romkyns Output could, for example, always be in 2011-01-02 format, and that's the one you'd put in your documentation. I see no detrimental effect at all. –  Izkata Jun 13 '12 at 14:07
4  
@Izkata: You misunderstood. Imagine there was an old program that is only available as binary. You have to write a new program that accepts the same inputs as the old. If the old program were well-defined in what it accepts, your job is well-defined. If it is lenient, then your job is impossible. –  Timwi Jun 13 '12 at 14:29
    
@Timwi I would call that Version 2. Details in API changes are acceptable, if documented. –  Izkata Jun 13 '12 at 14:48

Failing silently is the worst thing you could possibly do, ever. Have you tried to debug an API with silent failure? It's impossible.

There's "Do your best to recover but send detailed error" and there's "Silent failure".

share|improve this answer

It seems to me that Postel's Law -- "Be conservative in what you do, be liberal in what you accept from others" is what is being discussed for a JSON service. This is usually applied to web services and not UI.

For UI constructive user feedback and contraining user input is the rule of thumb we use.

share|improve this answer
    
But if you look at the answers here, everyone seems to agree that it only ever makes sense for UIs, i.e. the opposite of the original law. –  romkyns Jun 13 '12 at 17:36
    
I see what your saying, and agree with the posters that a clean strict API/Service is the goal, but for better or worse I know I have added 'robustness' in one form or another to my services. Usually a value translation or two at the boundery. As long as the meaning is clear, the app knows how to process the message and no business rules are violated then adding robustness will help interoperability. –  MarcLawrence Jun 14 '12 at 2:51
    
Until someone else goes and implements your spec, only to find that the "robustness", that hundreds of clients have come to rely on, was not actually in the spec and has to be reverse-engineered... –  romkyns Jun 14 '12 at 12:25

I think this is well covered in chapter 1, section 6 of TAOUP. Specifically, the rule of repair, which states that a program should do what it can with an input, pass correct data forward, and if the correct response is failure then do so ASAP.

A similar concept is defensive programming. You don't know what kind of input you will receive, but your program should be robust enough to cover all cases. This means there should be programmed in recovery cases for known problems like mangled input, and a catch all case to handle unknowns.

So discarding faulty input silently is fine, so long as you are handling that input. You should never just drop it on the floor, as it were.


For an API, I think being lenient is the same as for a program. The input is still wrong, but you are attempting to repair as much as possible. The difference is what is considered valid repair. As you point out, a lenient API can cause problems as people use "features" that don't exist.

Of course, an API is just a lower level version of the rule of composition. As such, it is really covered under the rule of least surprise, since it is an interface.

As the quote from Spencer notes, avoid superficial similarity, which can be argued about "fuzzy" inputs. Under these conditions, I'd normally argue that everything points to the program being unable to repair, because it won't know what is desired, and it is least surprising for the userbase.

However, you are dealing with dates which have many "standards". Sometimes these even get mixed in a single program(chain). Since you know that a date is expected, attempting to recognize the date is just good design. Especially if the date comes from some external program and gets passed unmodified through a second on it's way to you.

share|improve this answer

Programs that are deployed to server, most of the time, are supposed to take thousands of requests every minute, or sometimes every second. If a server program accepts and corrects faulty input from clients, I am afraid it will have 2 disadvantages:

  1. Loss of precious server time. With 1000+ requests per second, checking for faults in each request can reflect in slow response for each client.
  2. Unfair to the client/client-programs that provide correct input. Other than that, when a server side programmer sits on the server code, he/she has to think about the various cases of what faulty inputs can be. Who will decide that ?

Server programs should not accept faulty input, but the servers should return an error message to the client, if there is a faulty input.

share|improve this answer

The ideal behavior, conceptually, is to do what can be done safely, while simultaneously ensuring that someone who can fix any problems is somehow notified about them. In practice, of course, the latter constraint is often impossible to meet directly, and so the question becomes best to deal with dubious inputs.

One thing which can be very helpful in the design of a protocol, formatting spec, or "language" is to have a means of distinguishing four categories of potential non-understood items:

  1. Things which should be filtered out if not understood.
  2. Things which should be ignored if not understood, but nonetheless retained if data needs to be passed on (perhaps in some sort of wrapper to indicate that it has passed through at least one stage that didn't understand it)
  3. Things which should generate a warning if not understood, but should not prevent an attempt at data recovery (e.g. within a web page, an object whose type is unknown, but whose end within the file is well-defined, might be rendered as a red "X" without preventing the remainder of the page from being rendered.)
  4. Things which would indicate that anything that can't understand them is apt to have severe and unrecoverable problems elsewhere (e.g. an indicator that remaining data is compressed, and which anything that would be understood by anything which could perform the required uncompression).

Having a well-defined convention by which apps which can read any version of a data format will be able to recognize which category is appropriate for anything generated in compliance with later versions is a much better approach than attempting to wedge in ad-hoc compatibility measures later on. For example, if a file format has lines of the form "Tag: Value", one could specify that the first character of any tag will indicate the category in which it belongs; for tags of the silent-ignore categories, one could have the first character also indicate the version of the standard for which the tag is expected to be valid (so that if a "silent-ignore" tag claims to be present in version 3 of the standard, a parser for version would silently ignore it, but a parser for version 3 or later would squawk if it couldn't parse it).

The most important thing in any case is to avoid converting ambiguous or misunderstood data into erroneous data. In some cases, it may be better to refuse to propagate ambiguous data at all, though in other cases it may be better to propagate it precisely as received in case the recipient would regard it as unambiguous. What's truly dangerous if not downright evil is the conversion of data using varying assumptions, e.g. converting a list of dates like:

01/12/12
13/12/12
99/12/12

into a list of dates like

2012-01-12
2012-12-13
1999-12-12

Even if one had a list with a few erroneously-entered dates, it may be possible for a human given a list in the original format to determine which format was correct, and flag dubious values for further research (checking against other records, etc.) Rendering the dates in the latter format, however, would hopelessly and unrecoverably garble them.

share|improve this answer
    
Well said. I like how your answer goes a bit deeper. I am tempted to accept this, but given the overall interest this question has received, I think I'll leave this around for a while. –  romkyns Jul 10 '12 at 21:08

My UI experience comes mostly from desktop systems. Web sites are different, though I've seen a few sites that could challenge a desktop system. But for what it's worth:

I've found that error messages should be the very last resort; an ideal system would not have them at all. The best thing to do is not allow bad entries in the first place: the user can't enter "green" if he's selecting from a dropdown list of months. He can't push a grayed out button.

The next best thing to do is accept the bad data. Say you're displaying a histogram of daily sales for a month. After user input, the graph covers a century and the bar a century out is 10 times higher than the others. The user now knows he did something wrong and, futher, knows a lot more about what he did wrong than any message could tell him. When entry is graphical--by dragging a mouse, for instance--this kind of feedback still works and is invaluable. A bunch of the inputs may be invalid, but using this method the user gets instant, detailed feedback on the results of each mouse position.

All that said, sometimes the user needs to know why the button is grayed out so he can't push it. Then there's no help for it (if there is, let me know) but to ungray the button and, when he clicks on it, give him an good explanation of why the button isn't working at the moment.

share|improve this answer

The statement is about sending information over the internet. One of the things with sending information over the internet is that not always will it get to the target at all or fragmented.

share|improve this answer

Something that seems to be missed here--what are the consequences of failure?

Display a web page? You should do everything you can to tolerate bad input. Your choices are to display what you can or throw an error. The latter course gives the user nothing and thus should only be a last resort as it gives the user a completely useless result, it would be pretty hard for an error to be worse than this.

On the other hand, if it's asking for the target of a Minuteman III you reject "Moscow" as input as it's potentially ambiguous.

share|improve this answer
    
So even if you're a programmer, and you wrote some stupid code, the system should go ahead and do its best to show something, instead of just stopping and shouting "oi, you screwed up here (line number)"? Don't you think that's exactly what leads to incredibly bad code? –  romkyns Jul 11 '12 at 20:00
    
@romkyns: You have debug modes for that sort of thing that are strict about squawking about errors. –  Loren Pechtel Jul 12 '12 at 21:17

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.