dhesi@bsu-cs.UUCP (Rahul Dhesi) (02/17/89)
In article <1430@X.UUCP> john@frog.UUCP (John Woods) writes: >Then they showed an example of The New Wave, a four-line >error message which took 3 lines to misdiagnose the problem, and reminded >you that this was, in fact, an error. Yup. Just like VMS... :-) Hmmm...I hope they don't take it too far. TODAY (cryptic, confusing, not reassuring at all) $ xyz=test_symbol; export xyz $ sh $ ^D $ TOMORROW (warm, friendly, reassuring) $ xyz=test_symbol; export xyz %SHELL-I-SUPERSEDE, previous value of XYZ has been superseded %SHELL-I-EXPORT, of XYZ has been exported $ sh %SHELL-S-SPAWNED, process SHELL_002 spawned %SHELL-S-ATTACHED, terminal now attached to process SHELL_002 $ ^D Process SHELL_002 logged out at 16-FEB-1989 11:11:16.41 %SHELL-S-RETURNED, control returned to process SHELL_001 $ I'm not kidding. I actually did "define xyz test_symbol", "spawn", and "logout" at the VMS prompt and saw roughly the above. Here's what I would REALLY like to see: $ dir %DIR-Q-AREYOUSURE, you asked for a directory, are you sure [y/n]: y %DIR-Q-VERYSURE, you said yes, but are you REALLY sure [y/n]: y %DIR-Q-REALSURE, are you REALLY REALLY sure [y/n]: y %DIR-F-JUSTINCASE, no directory, say PRETTY_PLEASE $ dir/pretty_please %DIR-I-OHWELL, ok, well, if you insist %DIR-S-UASKED4IT, but we warn you, you did ask for it [ directory listing appears here] %DIR-I-DIRDONE, directory listing done, control returned to CLI %CLI-I-WHEW, *whew*, thought DIR was going to take over system $ -- Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee}!bsu-cs!dhesi ARPA: bsu-cs!dhesi@iuvax.cs.indiana.edu
jamesa@arabian.Sun.COM (James D. Allen) (02/21/89)
In article <5734@bsu-cs.UUCP>, dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: > Here's what I would REALLY like to see: Really? :-} > > $ dir > %DIR-Q-AREYOUSURE, you asked for a directory, are you sure [y/n]: y > %DIR-Q-VERYSURE, you said yes, but are you REALLY sure [y/n]: y > %DIR-Q-REALSURE, are you REALLY REALLY sure [y/n]: y > %DIR-F-JUSTINCASE, no directory, say PRETTY_PLEASE > $ dir/pretty_please > %DIR-I-OHWELL, ok, well, if you insist > %DIR-S-UASKED4IT, but we warn you, you did ask for it > [ directory listing appears here] > %DIR-I-DIRDONE, directory listing done, control returned to CLI > %CLI-I-WHEW, *whew*, thought DIR was going to take over system > $ This really made me laugh! From time-to-time I've wanted to mail some software to where_the_sun_doesnt_shine@software_vendor. Rahul's posting has induced me to give the net the benefit of my invective. :-} I only wish that superfluous dialog were the worst problem with friendly software. The "improved" `dir', for example, when it finally gets around to listing a directory, will silently substitute a *different* ("better", "friendlier") directory than the one you asked for. Here are two examples of programs which try to be helpful, but where I wish the programmer had called in sick the day he was going to add the feature. Example 1) IBM language processors abound with self-righteous "logic". Consider a C fragment like: /* * Temporarily disable database updates, until * the xlurg_gak module is debugged: */ #define write(X,Y,Z) \ (printf("Would have written %d bytes\n", Z), Z) This can be quite convenient. The macro definition doesn't "use" X or Y, but that is the intent. IBM has a macro facility in JCL, something like: //FOOBAR PROC X,Y,Z It's been a long time, but as I recall, typical output from `PROC' is: ILQJCL773P2: Fatal error, Formal argument `X' not used in `FOOBAR' If you think about the implementation, it's clear that somewhere in the JCL processor is code like: /* * The `refcnt' array is of no value to *us* whatsoever * but we need it for the friendly ILQJCL773P2 error. */ ++refcnt[var_index]; Great concept! A `fatal error' you have to go out of your way to detect and which, if undetected, would harmlessly have the desired effect (ie, none). Example 2) Just yesterday a friend asked me to help transfer some files from his Mac to his new Unix machine. First we connected a couple of wires between pins 2 & 3 and pins 3 & 2. Then we needed some software to get the wires busy. I'm sure everybody in this newsgroup could whip that together in a few minutes but my friend had already purchased a Mr_Everything_you_ever_wanted_to_do_with_your_serial_line application so we double-clicked its icon. I should have smelled trouble when I noticed the icon had a real *friendly* smile. We immediately got a "Password:" string safely back from the other end of the wire. "This will be real easy," I said. "Unix is smart enough to play stupid when you tell it to." I did something like % stty raw -echo % cat -u > foobar^J and selected Mr_Everything's "Send File" menu. "We'll have to `kill' `cat' from the other end, but that's harmless enough." However, Mr_Everything was too friendly to send a *binary* file over the wire. It doesn't care what the data is, mind you, just whether it recognizes the flavor of the mindless Macintosh file prefix. Summary) What are the reasons for this type of software "quality"? I nominate 1) Mediocre programmers only get a low bug-to-keystroke ratio with `printf'-type code so they do lots of it. 2) Too often, software quality is judged by managers who are not real users. 3) Programmers view themselves as more intelligent then their users, but ignore that their intelligence will be "out of the loop" once the software (a tiny subset of their skill) is delivered. Some will argue that my complaints are not caused because software is "friendly" but because "it isn't friendly enough!" But adding lots of features *increases* problems whenever the features prove inadequate. It's better to give the user a *simple* model of the software. This is the original Unix philosophy: - do something simple - do it well - do it silently Returning to the farcical version of `dir', for example, after receiving complaints about the inane dialog, the "friendly" solution is to add another option to `dir': $ dir/omit_inane_dialog %DIR-Q-IAMSOSAD, sure you want to omit the inane dialog? [y/n]: Friendly software. Just say no.
patrick@ism780c.isc.com (Patrick Curran) (02/22/89)
In response to various amusing comments about VMS's tendency to keep you over-informed about what it's doing: ======== While I'm no great fan of VMS, I did spend a couple of years working with it, and I really must correct the (mis)impressions that are being generated here. Yes, VMS's messages can be irritatingly wordy. However, it is possible to customize the message system to behave the way you want it to. I forget the precise details, but essentially there are several sorts of messages (informational, warning, error, system?), and each message has several components (a number, an identification of the program which issued the message, an indication of its type, and the message itself). It's possible to specify that you only want particular types of messages to be displayed, and/or that you only want to see particular message components. Consequently, if you want nothing but UNIX-style terse error messages (no fluff, no warnings, no informational messages) you can get them. If you want more, you can have that too. (Now that I think of it, if you're from the "real hackers don't need error messages" school, you could turn off all messages, so implementing the ultimate in silent systems :-) The advantage of the centralized error-message-handler is that user- written or third-party programs can utilize its capabilities, inserting their own messages into the database. All (well-written) programs therefore behave in exactly the same way. Similar capabilities exist for adding user-supplied help messages to the system help database, and for accessing the command-line parsing capabilities of the CLI. The result is a much cleaner interface; users know how to invoke programs, how to get help while using them, and how to interpret the messages they produce. Sounds to me like a big win over the current state of affairs in the UNIX world. The sooner we implement something similar, the sooner we'll be taken seriously in the real world where people run applications rather than hack software. Patrick Curran (uunet!ism780c!patrick) INTERACTIVE Systems Corp, Santa Monica, CA. (213) 453-8649
warner@hydrovax.nmt.edu (M. Warner Losh) (02/23/89)
In article <5734@bsu-cs.UUCP>, dhesi@bsu-cs.UUCP (Rahul Dhesi) writes...
->Hmmm...I hope they don't take it too far.
This is agreed. There is nothing more irritating than seeing:
%BASIC-F-EXESTA, Execution of statement failed
-BASIC-F-LETFAI, LET command failed
-BASIC-F-RHSNOVAL, Right hand side could not be evaluated
-BASIC-F-NOSTRING, String could not be created
-BASIC-F-NOMEMORY, Memory allocation failure
When
%BASIC-F-EXEABO, Execution aborted
-BASIC-E-LETFAI, LET command failed at line 123 in GEORGE.xxx
-SYSTEM-F-NOMEMORY, Memory exhaused
would do just as well.
It is informative and gives a clue where things died w/o going overboard.
(BTW, I have worked with a product on VMS that actually does the first thing
whenever it encounters an error. Guess the developers of that product
didn't completely understand the error facilities they were using :-)
->TODAY (cryptic, confusing, not reassuring at all)
-> $ xyz=test_symbol; export xyz
-> $ sh
-> $ ^D
-> $
And totally uninformative.
->TOMORROW (warm, friendly, reassuring)
-> $ xyz=test_symbol; export xyz
-> %SHELL-I-SUPERSEDE, previous value of XYZ has been superseded
-> %SHELL-I-EXPORT, of XYZ has been exported
-> $ sh
-> %SHELL-S-SPAWNED, process SHELL_002 spawned
-> %SHELL-S-ATTACHED, terminal now attached to process SHELL_002
-> $ ^D
-> Process SHELL_002 logged out at 16-FEB-1989 11:11:16.41
-> %SHELL-S-RETURNED, control returned to process SHELL_001
-> $
I contest that this is user friendly. It is informative, and lets you know
exactly what is going on. Granted, there should be an easy way to globally
turn the chatter off.
->I'm not kidding. I actually did "define xyz test_symbol", "spawn", and
->"logout" at the VMS prompt and saw roughly the above.
Ah, but if you place the following in your startup file on VMS, you can
get rid of the obnoxious messages:
$ DEF*INE :== DEFINE/NOLOG
$ SPA*WN :== SPAWN/NOLOG
(Which solves the immediate problem.)
-or-
$ SET MESSAGE/NOTEXT/NOID/NOSEV/NOFAC
Which tells the system not to bother you at all with any error messages.
[Rediculous example deleted]
This example is so rediculous, that any programmer that makes his programs
do this by default should be shot.
BUT the point is well taken: Provide good error messages and a consistant
user interface, but please don't over do it.
->Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee}!bsu-cs!dhesi
--
Warner Losh
warner@hydrovax.nmt.edu ...!unmvax!nmtsun!warner%hydrovax
What happened to our innocence, did it go out of style?
My spelling and views are my own. Only the letters have been changed...
stpeters@dawn.steinmetz (02/23/89)
In article <22569@ism780c.isc.com> patrick@ism780c.UUCP (Patrick Curran) writes: >Yes, VMS's messages can be irritatingly wordy. However, it is possible >to customize the message system to behave the way you want it to. Not really. For example, if you turn off all the components, you never get *any* error messages, which is a bit more terse than even UNIX. However, even if you have the messages turned off, VMS will still inform you that you've logged off. Rather handy, that. :-) There are other things too. Fortunately, I don't have to use VMS much anymore, so I don't remember what they are, but they were once a pain. >The result is a much cleaner interface; ... >Sounds to me like a big win over the current >state of affairs in the UNIX world. The sooner we implement something >similar, the sooner we'll be taken seriously in the real world where >people run applications rather than hack software. >Patrick Curran (uunet!ism780c!patrick) >INTERACTIVE Systems Corp, Santa Monica, CA. (213) 453-8649 Well, Pat, we were once an all VMS site. Management was a little slow noticing that 1) most of the applications we ran were ported from UNIX, and 2) every time they bought a VMS machine they wound up shelling out thousands of dollars for INTERACTIVE's UNIX emulation. Finally, they let us have real UNIX. We've been happily running applications ever since. More and more the business components of GE have been doing so as well. -- Dick St.Peters GE Corporate R&D, Schenectady, NY stpeters@ge-crd.arpa uunet!steinmetz!stpeters
dave@whoops.celerity (Dave Smith) (02/23/89)
[much funny material about VMSization of Unix deleted] This reminds me of when DEC was VMSizing RSTS/E (a PDP-11 operating system sometimes reminiscent of CP/M). Digital was making a push to get rid of the old commands, like PIP, SYSTAT (similar to who) and replace them with the Damned Command Language, which had verbose monstrosities like SHOW USERS/ALL. My complaint was that commands like this were entirely too verbose to use all the time and too easy to misspell. DEC's answer was that one, these verbose commands were more mnemonic and two, if you wanted to you could abbreviate to SH US/AL. Somehow, SH US/AL made a lot less sense to me than SYSTAT which was mnemonic and easy to type. Oh well, that was about the time I discovered Unix and found out what cryptic _really_ meant! David L. Smith FPS Computing, San Diego ucsd!celerity!dave "Repent, Harlequin!," said the TickTock Man
bzs@Encore.COM (Barry Shein) (02/24/89)
>The result is a much cleaner interface; users know how to invoke >programs, how to get help while using them, and how to interpret the >messages they produce. Sounds to me like a big win over the current >state of affairs in the UNIX world. The sooner we implement something >similar, the sooner we'll be taken seriously in the real world where >people run applications rather than hack software. > >Patrick Curran (uunet!ism780c!patrick) You miss the whole point of Unix's terseness. The point is that the output of one command is intended to be useful as the input of another command, or, the terminal. It's not a "user-friendly" issue or decision, it's a productivity decision. VMS doesn't have pipes and often produces output its other programs can't read anyhow, due to the zillions of RMS file format mismatches (even if you manage to figure out how to save it to a file, no I/O redirection) so it's comparing apples and oranges, who cares if it's full of "RMS-I-EVERYTHING-A-OK" messages, it's just zipping off the screen anyhow (no piping to "more" either, lovely, user-friendly system, zip zip zip...what was that?) It's nice to hear there's some way to shut it up but that really begs the point (ie. the design of VMS.) Being as VMS never considered the output of its programs very useful they felt free to babble whatever they wanted and generally make it impossible to ever parse up. In unix the designers preferred the output of programs to be useful. I realize people find this point aggravatingly subtle. -Barry "Keen Eye for the Obvious" Shein, ||Encore||
bzs@Encore.COM (Barry Shein) (02/24/89)
Cryptic is in the eye of the beholder. Consider a voice-communications system which required you to type in 7 to 10 digit strings to establish virtual circuits! AT&T has done fairly well with this design, and it's not obvious that any change would be for the better. The most amazing part of any technology are the people who use it, be careful when playing armchair psychologist. -Barry Shein, ||Encore||
guy@auspex.UUCP (Guy Harris) (02/25/89)
>The point is that the output of one command is intended to be useful >as the input of another command, or, the terminal. Output, or error output? The error output of commands *should* be intended to be useful to the poor sap who's trying to use the command, even at the expense of making it harder for some program to parse.
guy@auspex.UUCP (Guy Harris) (02/25/89)
>Cryptic is in the eye of the beholder. Consider a voice-communications >system which required you to type in 7 to 10 digit strings to >establish virtual circuits! AT&T has done fairly well with this >design, and it's not obvious that any change would be for the better. Yes, at times I've noticed the annoying similarity between the error messages UNIX coughs up and the error messages the phone system coughs up.... Whilst a change to the scheme for dialing may or may not represent an improvement, other aspects of the phone system *could* be changed in ways that, at least from the end-user's viewpoint, would be for the better. One example is the moral equivalent of the "syntax error" message. You know, the one that starts with that horrible shriek (which, I seem to remember hearing, is required by some standard, so that one may not be AT&T's fault), and then informs you that "your call cannot be completed as dialed". This is about as annoying as, say, the "foo: alpha/beta/gamma: cannot open" messages that UNIX programs tend to cough up. A change that is obviously for the better is to have those messages print out the error message associated with "errno", so you don't have to try an "ls" to see if the file doesn't exist, or exists but doesn't let you read it, or.... The moral equivalent of such a change to the phone system user interface would be for it to tell you something like "that call's in your area code, dummy, leave the area code off!" An even better change would be for it to ignore the area code; I don't know whether either change is possible - it may well not be, and it may be too expensive to change the phone system to support it, and may have been too expensive to built the phone system to support it. The same isn't true of UNIX; using "perror", or using "sys_nerr" and "sys_errlist", isn't that costly. (Also, going back to the original point, consider a networking system that required you to type in N-digit strings to specify host addresses in individual configuration files for various network services; a change that centralized the host-name-to-address mapping and let all the services use that mapping, so that their configuration files could have names, would be a change for the better.) >The most amazing part of any technology are the people who use it, >be careful when playing armchair psychologist. Well, I *have* used UNIX and the phone system, and yes, there are places in both where the cryptic error messages simply suck. Ever tried debugging a long "ed" script with a version of "ed" that *cannot* be told to print long error messages? I made the SunOS 4.0 "ed" print *line numbers* when it's in "long error messages" mode - as turned on by the "H" command, since that "ed" is derived from the S5R3 "ed" - and was given the "-" option. That made it *lots* easier to debug big "ed" scripts such as the ones used when building the S5R3 "curses" library. People too often seem to take it for granted that short, cryptic error messages are ultimately a Good Thing under all circumstances and that UNIX has nothing to learn or to improve in this regard. It's simply not true. (Why did not "ed" print TECO-style short error messages instead of just "?"? As I remember, DEC TECO printed error messages with a "?" followed by a 3-letter code, or maybe vice versa. Terse, but at least it doesn't throw away information....) None of this is to say that VMS-style error messages necessarily represent an improvement, just that there *is* plenty of room for improvement in UNIX's error messages. (At least we no longer have botches such as "ar" printing its error messages to standard output; well do I remember doing "ar t foo.a | lpr" and getting one sheet of printout saying "foo.a does not exist"....)
guy@auspex.UUCP (Guy Harris) (02/27/89)
>Ah, but Guy, if the phone system were more like VMS then they'd surely >have to charge you for unanswered calls and the like or they'd go >broke! I neither want UNIX nor the phone system to be "more like VMS" in that regard. I just want them to be less prone to withholding information from me when reporting an error, since that information could allow me more quickly to fix the problem they're reporting. I also don't want to see people equating "better error messages" with "error messages like VMS", either when arging against better error messages or when trying to improve them!
merlyn@ernie.Rosemount.COM (Brian Westley) (02/28/89)
>Cryptic is in the eye of the beholder. Consider a voice-communications >system which required you to type in 7 to 10 digit strings to >establish virtual circuits! AT&T has done fairly well with this >design, and it's not obvious that any change would be for the better. > -Barry Shein, ||Encore|| It's easy to do better; phone USED to work better. You picked up the phone and said "John Q. Public, please" and that was all. I bet phones will do this in the future, only you'll be talking to a voice recognition circuit instead of a human. It'll also know who YOU mean if you ask for "John" or "Mom" or whomever. Merlyn LeRoy
consult@osiris.UUCP (Unix Consultation Mailbox ) (02/28/89)
Despite the fact that a lot of people have a lot to say (or flame) on this issue, it seems that there is really very little controversy, at least about what error messages should say. The consensus seems to be (correct me if I'm wrong.. :-) that error messages should say just enough to please the user and no more. The problem here is (of course) defining the term "user". The same problem exists with the term "user-friendly". It's not possible to lump all users of any commercial computer system into a single group with definite and consistent interface preferences. This applies to error messages as well as the syntax of a command-line interface or whether the system has a command-line at all (e.g. Mac). In general I won't touch anything "user-friendly" with a ten-foot mouse. This is because I personally find the typical "user-friendly" interface to be anything but a help to software development. I already understand the system I am working on pretty well; I am familiar with navigating UNIX filesystems, making system calls, predicting the effect of wildcards in shell scripts, etc. I don't want to be led by the hand through fifteen nested menus to get into an editor. I don't want to ever *have* to use a mouse - I've been a touch-typist since long before I ever worked with computers and because I *write text* for a living, it's much more important for me to have my fingers on the home keys than to be able to point to a menu selection when I'm just trying to logout. We write applications on UNIX systems which run on UNIX systems and are used by (largely) unskilled users. We have to be very careful about what our "users" see, that it is as consistent as possible between systems and neither cryptic nor prolix. When our programmers are called upon to second-guess the users by predicting the acceptability of a certain feature, they frequently get it wrong because they are looking at the system from a completely different angle. (We are slowly learning that we don't have the smarts to outguess our "unsophisticated" users.) I don't like systems that assume that I have no experience with them. Many other programmers that I work with feel the same. Some don't. Some otherwise perfectly good programmers always have to be led very carefully the first time through something or they won't get it. On the other side of the coin, some applications try to assume that the "user" knows a lot more than they really do; most of our "users" don't like it when our systems do this, though some do. I think the fundamental problem here is that some people haven't yet figured out that they are trying to make everybody happy at once, which we know (cf. Heisenberg :-) cannot be done in reality, whatever that is. I'll keep using UNIX as long as I can, unless I find something I like better. I have so far found no "user-friendly" interfaces which I find more intuitive or productive than the Bourne shell. If I ever do, I'll be sure to let everyone know. :-) Phil Kos Curmudgeon Supreme
jacobson@karachi. (Dan Jacobson) (02/28/89)
I remember this VMS nastiness: %E-BUZZOFF Foreign commie terminal type. By a DEC terminal and reenter command -- Dan Jacobson, jacobson@eecs.nwu.edu, {oddjob,gargoyle,att,...}!nucsrl!jacobson
guy@auspex.UUCP (Guy Harris) (03/01/89)
>The consensus seems to be (correct me if I'm wrong.. :-) that error >messages should say just enough to please the user and no more. Yes. However, one gets the impression that some programmers have a quite bogus idea of how much this actually is - often bogusly small. If I have to dive into the source code to figure out what the problem is, and then find that it's, say, some straightforward error in a configuration file, the person who designed the error messages screwed up. If I have to "ls" a file to figure out whether the application couldn't open it because it doesn't exist, or because it's not readable/writable by me, or because it's on a read-only file system, or..., the person who designed the error messages screwed up - especially given that the "open" call will tell you that, so all they had to do was *not* to throw out the information stashed in "errno"! >The problem here is (of course) defining the term "user". And one of the main problems is that they too often define "user" as "wizard" - or, worse, assume that "the experienced user can" - and *should* - "figure out what's wrong". Even wizards sometimes get *really* ticked off at cryptic error messages; yes, they *can* - eventually - figure out what the problem is, but they often don't like playing 20 Questions with the machine in order to do so. I've been working with UNIX for over 10 years now, and I *still* find many of its error messages to be quite poor, although they have slowly gotten better over time - yes, I can poke at enough things and figure out what the *real* problem is, eventually, but I'd rather *not* be forced to do so, especially if the computer could have added some extra bit of information to its messages that would have told me what the real problem was immediately. >The same problem exists with the term "user-friendly". It's not >possible to lump all users of any commercial computer system into >a single group with definite and consistent interface preferences. >This applies to error messages as well as the syntax of a command-line >interface or whether the system has a command-line at all (e.g. Mac). The term "user-friendly" doesn't denote very much. It *con*notes quite a bit, but the connotation depends on the audience; if it's some bunch of novices, it's intended to connote Motherhood, Apple Pie, and the Flag, and if it's some bunch of UNIX hackers, it's often intended to connote Satan and grape Flavor-Aid. In the former case, it can be used to make some not-so-wonderful package sound better than it is, and in the latter case it can be used to inappropriately dismiss some reasonable ideas. In other words, the issue of whether mouse-based user interfaces are good or bad has a lot less to do with the issue of how noisy an application might be in the face of errors that is often thought.
campbell@redsox.UUCP (Larry Campbell) (03/01/89)
Having spent the last year or so trying, among other things, to help our customers use our software, I have developed some very strong opinions on the subject of error messages: 1. Messages must be accurate and relevant. This should go without saying, but the infamous "not a typewriter" message reminds me that it bears repeating. 2. Messages must be complete. If the problem is related to a particular entity (file, process, device), the entity MUST be named. "File not found" is useless -- you must tell me *which* file you were trying to find! 3. Messages must not be excessively scary. Words like "illegal", "corrupted", "damaged" and the like should be avoided. They *will* result in telephone calls which *cost* *you* *money*. 4. If there's anything the user can do about the error, the message must be understandable and must suggest a course of corrective action. But if it's just a bug the user can't do anything about, the message should direct the user to call customer support, and it should display enough information so the poor support person has half a chance of fixing the problem. 5. It is better to give too much information than too little. You can always ignore the excess information, but when you're trying to support a customer six time zones away, you're going to want as much information as possible to be available. Remember, the hard problems aren't repeatable, and even if they were, it's too expensive to keep a customer on the phone trying things out for you. I once attended a lecture given by Ben Schneiderman (Univ. of Md.) about human factors engineering. He pointed out that the best error message he knew of was the one you get when you misdial a phone number (this was before divestiture): "We're sorry, but we are unable to complete your call as dialed. Please check the number and try your call again, or call your operator for assistance." This is an excellent error message, for the following reasons: 1. "We're sorry," It starts out by apologizing! For your mistake! 2. "We are unable..." It blames itself, and not the user! 3. "Please check the number..." It suggests not one, but two alternative courses of corrective action. In contrast, if compter programmers had designed the message, it would probably say something like: %ATT-F-INVADDR, Invalid or incomplete address, call aborted or Not a typewriter which, to the average user, would be frightening, confusing, and almost completely uninformative. -- Larry Campbell The Boston Software Works, Inc. campbell@bsw.com 120 Fulton Street wjh12!redsox!campbell Boston, MA 02146
vfm6066@dsacg3.UUCP (John A. Ebersold) (03/03/89)
In article <1089@auspex.UUCP> guy@auspex.UUCP (Guy Harris) writes: >>The consensus seems to be (correct me if I'm wrong.. :-) that error >>messages should say just enough to please the user and no more. > >Yes. However, one gets the impression that some programmers have a >quite bogus idea of how much this actually is - often bogusly small. Yes, like printing errno, instead of the error message. On a releated topic... How many times has anyone heard (or said) something like. "I'm not checking the return value becuase I can't do anything about it anyway." To me, this is not true. You can always print a message that says: Horrible error in program foo, function bar, the function bletch returned a -1 on about line x. I'd rather have this than a mysterious failure. -- John A. Ebersold at Defense Logistics Agency osu-cis!dsacg1!dsacg3!vfm6066 Unify Corporation System Automation Center Columbus, Ohio 1-614-238-5923 Me? Speak for anyone else? Don't be ridiculous! AV 850-5923 Systems with poorly understood requirements cannot be developed in a crunch.
peter@ficc.uu.net (Peter da Silva) (03/03/89)
Have you looked at the new "perror()" docs? They describe a 4-component error message format for all programs to use, containing the name of the program issuing the message, the name of the object responsible, the error message itself, and a severity level (INFO, WARNING, ERROR, FATAL). Like this: % cat /dev/dull cat: fatal: /dev/dull: No such file or directory Unfortunately, they still haven't bothered to make all programs use perror() itself! This, all by itself, would take care of the biggest problems with UNIX error messages. You get this: % cat /dev/dull cat: cannot open /dev/dull % nm /dev/dull nm: can't open "/dev/dull" % file /dev/dull /dev/dull: cannot open Doesn't exist? File not found? What? At least they could do this: % more /dev/dull /dev/dull: No such file or directory That's more like it. It'd take one summer student to fix this. Sigh... -- Peter da Silva, Xenix Support, Ferranti International Controls Corporation. Work: uunet.uu.net!ficc!peter, peter@ficc.uu.net, +1 713 274 5180. `-_-' Home: bigtex!texbell!sugar!peter, peter@sugar.uu.net. 'U` People have opinions. Companies have policy. And typos are my own business.
gwyn@smoke.BRL.MIL (Doug Gwyn ) (03/03/89)
In article <3283@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes: >Have you looked at the new "perror()" docs? They describe a 4-component >error message format for all programs to use, containing the name of the >program issuing the message, the name of the object responsible, the error >message itself, and a severity level (INFO, WARNING, ERROR, FATAL). > cat: fatal: /dev/dull: No such file or directory perror() CANNOT do this, as its interface is standardized and has no room for the additional information (severity and object; the program name can and probably should be automated). Presumably there is an analogous function that accepts the additional information. The specs for this interface would be very handy; we could implement it and start using it now, rather than having to wait a year. Generally I approve of the extended message format and agree that it needs to be used by (nearly) all the standard system utilities. What is supposed to be done when there is no particular object? prog: fatal: ???: Insufficient memory available
gwyn@smoke.BRL.MIL (Doug Gwyn ) (03/03/89)
In article <1369@dsacg3.UUCP> vfm6066@dsacg3.UUCP (John A. Ebersold) writes:
-How many times has anyone heard (or said) something like. "I'm not checking
-the return value becuase I can't do anything about it anyway."
-To me, this is not true. You can always print a message that says:
-Horrible error in program foo, function bar, the function bletch returned a
--1 on about line x.
-I'd rather have this than a mysterious failure.
I agree with you in general; however, there's one common case where the
best solution seems to be to ignore the failure: when an attempt to
output an error message (to stderr, usually) fails. What are you going
to do, try to print yet another error message?
The "assert" macro defined by "#include <assert.h>" is very handy for
handling program logic bugs, in many cases. Sometimes it is important
to try to recover from an error and resume normal operation, rather
than terminating the process.
peter@ficc.uu.net (Peter da Silva) (03/06/89)
In article <9780@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn ) writes: > In article <3283@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes: > >Have you looked at the new "perror()" docs? They describe a 4-component > >error message format for all programs to use... > perror() CANNOT do this, as its interface is standardized and has no > room for the additional information (severity and object; the program > name can and probably should be automated). I realise this. The document describes what programs should do for error messages, but makes no recommendation as to how this should be done. > Presumably there is an > analogous function that accepts the additional information. Unfortunately it's like Open Look... they just specced what it should look like without providing a programmer interface. The documentation has been out in the bookstores for some time: it's a red book with a plastic spiral binding. > What is supposed to be done when there is no particular object? > prog: fatal: ???: Insufficient memory available What does perror do when there is no particular object? if(!(buffer = malloc(BUFSIZ*NUMBUFS))) { perror(.....?.....); ... } Same problem. Perhaps we (the usenet community) should spec a better interface: extern char *progname; extern char *errformat; extern char default_errformat[]; char *errmsg(); main(argc, argv) int argc; char **argv; { progname = argv[0]; errformat = getenv("ERRORFORMAT"); if(errformat == NULL) errformat = default_errformat; ... } ... fprintf(stderr, "%s\n", errmsg(object, severity)); errformat would be printf/sccs-like: %p program name %P program name, tail only (no path). %o object %e error message %E short error message %s severity %S severity, 1 char %E %p: %s: %o: %e %Q %o: %e -- Peter da Silva, Xenix Support, Ferranti International Controls Corporation. Work: uunet.uu.net!ficc!peter, peter@ficc.uu.net, +1 713 274 5180. `-_-' Home: ...!texbell!sugar!peter, peter@sugar.hackercorp.com. 'U` People have opinions. Companies have policy. And typos are my own business.
lee@ssc-vax.UUCP (Lee Carver) (03/07/89)
In article <1369@dsacg3.UUCP>, vfm6066@dsacg3.UUCP (John A. Ebersold) writes: > In article <1089@auspex.UUCP> guy@auspex.UUCP (Guy Harris) writes: > >>The consensus seems to be (correct me if I'm wrong.. :-) that error > >>messages should say just enough to please the user and no more. > > > >Yes. However, one gets the impression that some programmers have a > >quite bogus idea of how much this actually is - often bogusly small. > > Yes, like printing errno, instead of the error message. > Actually, the problem is that there is NO right level of detail. The slickest approach I've seen is to let the user decide how much detail to look at. No surpisingly, this approach is well based in cognitive psychology. A recent CACM paper (K Efe, "A proposed solution to the problem of levels in error-message generation", CACM, vol 30, no 11, Nov 1987, pg 948) provides a very simple implementation. It allows the user to review the failed execution, and uncover the problem. It also starts with a good discussion of why a single error message is inadequate. Basically, it put the programmer in the position of arrogantly "knowing" what the user wants. For those without the paper, it is basically a tarceback stack in user sensible terminalogy. You don't have to implement all the "what next" capability in his paper to have a useful error system. Lee Carver Boeing Aerospace
davidsen@steinmetz.ge.com (William E. Davidsen Jr) (03/07/89)
In article <1369@dsacg3.UUCP> vfm6066@dsacg3.UUCP (John A. Ebersold) writes: | On a releated topic... | | How many times has anyone heard (or said) something like. "I'm not checking | the return value becuase I can't do anything about it anyway." | | To me, this is not true. You can always print a message that says: | | Horrible error in program foo, function bar, the function bletch returned a | -1 on about line x. | | I'd rather have this than a mysterious failure. I've done this many times. What would you do when you get an error, for instance, writing stderr? When I detect a serious error I attempt to output a warning message to terminal and/or files as appropriate, then clean up as best I can. When something is seriously wrong writing error messages, etc, can mess up additional parts of the program. -- bill davidsen (wedu@ge-crd.arpa) {uunet | philabs}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me
jgp@moscom.UUCP (Jim Prescott) (03/29/89)
In article <3314@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes: >Perhaps we (the usenet community) should spec a better interface: A nice quick 90% solution is a printf-like function that writes to stderr, prepends the program name to the message, and can append the system error message. Something like: if (open(fname, O_RDRW, 0) == -1) errmsg("Cannot open \"%s\" for read/write -- ", fname); would output: prog: Cannot open "somefile" for read/write -- Read-only file system This makes it fairly painless for the programmer to come up with an informative message without worrying about the little details. Trying to use perror to get a nice message is too much work, which is probably why it isn't used as often as it should be. The problems in implementing this are: - finding the program name; most likely needs to be stashed away while in main(). (It would have been nice if the ANSI-C folks had invented some globals to hold copies of main's arguments. (I know it isn't their job to invent :-).) - deciding where to put the system error. The code below tacks it on the end of the message iff it doesn't end in a newline. Not a great solution but certainly much simpler than doing a new % escape. An enhancement would be introduce error levels (we use FATAL, ERROR, INFO and DEBUG) and provide some way to specify which you want to see (we default to FATAL & ERROR). I've even enclosed a function to implement it below (about 99% of which is from an article on varargs by Chris Torek). I'm not sure how portable vsprintf is, its on our sun but wasn't in V7 so it probably isn't universal. If anyone can tell me where to get a pd vsprintf I'd be grateful. While we're on the subject, Guy mentioned TECO error messages but not how nifty they actually are. You can tell it to print just the 3 letter code (eg. ?FNF), to print the 1 line error (eg. ?FNF File not found.) or to print the 1 line message followed by a couple of likely paragraphs out of the manual (this is called "war and peace" mode). Its flexible even if not overly useful (I can't imagine using anything other than 1 line messages. Maybe the 3 letter only would be good on 110 baud ttys). ========= varargs version #include <varargs.h> int errmsg(va_alist) va_dcl /* N.B.: no semicolon */ { int ret; char *fmt; va_list ap; char buf[1024]; /* shouldn't be fixed size */ va_start(ap); fmt = va_arg(ap, char *); ret = vsprintf(buf, fmt, ap); va_end(ap); fprintf(stderr, "%s: %s", Progname, buf); if (*(buf + strlen(buf) - 1) != '\n') perror(""); return ret; } #endif ========= stdarg version #include <stdarg.h> int errmsg(char *fmt, ...) /* the `...'s are part of the syntax */ { int ret; va_list ap; char buf[1024]; /* shouldn't be fixed size */ va_start(ap, fmt); ret = vsprintf(buf, fmt, ap); va_end(ap); fprintf(stderr, "%s: %s", Progname, buf); if (*(buf + strlen(buf) - 1) != '\n') perror(""); return ret; } -- Jim Prescott moscom!jgp@cs.rochester.edu {rutgers,ames,harvard}!rochester!moscom!jgp
chris@mimsy.UUCP (Chris Torek) (03/30/89)
In article <1411@moscom.UUCP> jgp@moscom.UUCP (Jim Prescott) writes: [much deleted; these are retained in order] > ret = vsprintf(buf, fmt, ap); > fprintf(stderr, "%s: %s", Progname, buf); > perror(""); Beware, beware! His flashing eyes, his floating exception! Oops, a bit of stream of unconsciousness there. This can produce the infamous sendmail-style message: Cannot exec /bin/mail: Not a typewriter because fprintf() can call isatty() which can set errno to ENOTTY. To fix this you should either save and restore errno, or change the code to fish the error message directly out of sys_errmsg[], or use strerror() (if your C library has it). -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
peter@ficc.uu.net (Peter da Silva) (03/30/89)
Neither of these solutions is correct: In article <1411@moscom.UUCP>, jgp@moscom.UUCP (Jim Prescott) writes: > fprintf(stderr, "%s: %s", Progname, buf); > if (*(buf + strlen(buf) - 1) != '\n') > perror(""); If this is the first time I/O is done, on at least some machines stdio will call isatty(0) to determine if stdout should be unbuffered. It will not save and restore errno. Your program may give such useful advice as: foobar: can't open file barfoo -- Not a typewriter. or: foobar: can't open file barfoo -- Inappropriate ioctl for device. -- Peter da Silva, Xenix Support, Ferranti International Controls Corporation. Business: uunet.uu.net!ficc!peter, peter@ficc.uu.net, +1 713 274 5180. Personal: ...!texbell!sugar!peter, peter@sugar.hackercorp.com.
daveh@marob.MASA.COM (Dave Hammond) (03/31/89)
In article <1411@moscom.UUCP> jgp@moscom.UUCP posts his favorite error
message printer.
I note that for a return value it provides the return from vsprintf.
Since error message printers are typically invoked prior to a return,
or exit, I opt to have my favorite error printer return -1.
While this, perhaps, bastardizes the significance of the function's return
value, it (more often than not) makes for convenient error handling:
...
if (an_error_occurred)
return(errmsg(errcode, "Can't open file %s.", fname));
Obviously this presumes that the calling function normally returns -1 as
an its error condition value. Functions which don't employ a -1 error
return just void the return from the error printer.
--
Dave Hammond
daveh@marob.masa.com
guy@auspex.UUCP (Guy Harris) (03/31/89)
>A nice quick 90% solution is a printf-like function that writes to stderr, >prepends the program name to the message, and can append the system error >message. Something like: > if (open(fname, O_RDRW, 0) == -1) > errmsg("Cannot open \"%s\" for read/write -- ", fname); >would output: > prog: Cannot open "somefile" for read/write -- Read-only file system CAREful - you may want to call this function for errors that *don't* cause "errno" to be set. You might want to have some way to indicate whether it should use "errno" or not - or, perhaps, just use the (dp)ANSI C routine "strerror", which takes an "errno" as argument and returns a pointer to the appropriate error message string, and just stick "%s"es into the message string and calls to "strerror" into the argument list. (If your implementation doesn't have "strerror", it's probably a 5-minute job to whip one up, at least under UNIX.) >This makes it fairly painless for the programmer to come up with an >informative message without worrying about the little details. Trying >to use perror to get a nice message is too much work, which is probably >why it isn't used as often as it should be. Yes, but unfortunately burying the call to "perror" in "errmsg" has its own problems. Note also that there are places other than "errno" where errors are reported (by other packages, such as TLI, ONC RPC, database libraries, etc.), often with their own families of error codes and messages, so you may end up having to stick calls to the "return error message" code in *anyway* in some cases....
jfc@athena.mit.edu (John F Carr) (04/01/89)
I include in this article a manual entry for a library function for error
reporting developed by the Student Information Processing Board at MIT.
This is useful because it allows libraries to define their own set of
error codes and messages without adding any user level error processing
code. Library functions can return an internal error code or a unix error.
The com_err function recognizes the type of error and prints an appropriate
message. Each library is given its own range of error codes to avoid
conflict.
It is still possible to print useless or incomprehensible error messages
when using this library, but it encourages a consistent, hopefully good,
style of error reporting.
COM_ERR(3) UNIX Programmer's Manual COM_ERR(3)
NAME
com_err - common error display routine
SYNOPSIS
#include <com_err.h>
void com_err (whoami, code, format, ...);
const char *whoami;
long code;
const char *format;
proc = set_com_err_hook (proc);
void (* proc ) (const char *, long, const char *, va_list);
proc = reset_com_err_hook ();
void initialize_XXXX_error_table ();
DESCRIPTION
Com_err displays an error message on the standard error
stream stderr (see stdio(3S)) composed of the whoami string,
which should specify the program name or some subportion of
a program, followed by an error message generated from the
code value (derived from compile_et(1)), and a string pro-
duced using the format string and any following arguments,
in the same style as fprintf(3).
The behavior of com_err can be modified using
set_com_err_hook; this defines a procedure which is called
with the arguments passed to com_err, instead of the default
internal procedure which sends the formatted text to error
output. Thus the error messages from a program can all
easily be diverted to another form of diagnostic logging,
such as syslog(3). Reset_com_err_hook may be used to
restore the behavior of com_err to its default form. Both
procedures return the previous ``hook'' value. These
``hook'' procedures must have the declaration given for proc
above in the synopsis.
The initialize_XXXX_error_table routine is generated mechan-
ically by compile_et(1) from a source file containing names
and associated strings. Each table has a name of up to four
characters, which is used in place of the XXXX in the name
of the routine. These routines should be called before any
of the corresponding error codes are used, so that the
com_err library will recognize error codes from these tables
when they are used.
The com_err.h header file should be included in any source
file that uses routines from the com_err library; executable
files must be linked using ``-lcom_err'' in order to cause
the com_err library to be included.
SEE ALSO
compile_et (1), syslog (3).
Ken Raeburn, "A Common Error Description Library for UNIX".
-------
Here is an example of its usage (from "zwgc", the main client for the
Zephyr message delivery service):
if ( (nzqueued = ZPending()) == -1 )
{
if(errno == ZERR_EOF)
{
com_err("zwgc",errno," on select");
exit(-1); /* if eof, we still can't exit_cleanly */
}
--
John Carr "When they turn the pages of history,
jfc@Athena.mit.edu When these days have passed long ago,
bloom-beacon! Will they read of us with sadness
athena.mit.edu!jfc For the seeds that we let grow?" --Neil Peart