OS APIs without error codes

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: OS APIs without error codes

Post by Gigasoft »

switch (file.Error())
{
case FileNotFound: //...
case FileLocked: //...
case FileAccessNotPermitted: //...
}
I think //... is the important part here. It usually doesn't matter to an application how something went wrong - there is nothing it can do about it anyway. Either the hardware malfunctioned, or the programmer made a mistake. If the programmer made a mistake, he should have discovered it during testing. If a piece of the hardware has malfunctioned, it should be obvious to customer support after some investigation.

As for receipt printers, they normally don't return error codes. Instead, they report their status when there is a change or when requested by the user, so it doesn't make sense for the system to make up an error code. I am guessing that regardless of what the problem is, it is handled by displaying something like "Out of order - Please contact the staff" on the screen and halting.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: OS APIs without error codes

Post by Brendan »

Hi,
Gigasoft wrote:I think //... is the important part here.
Ok:

Code: Select all

retry:
    status = file.Error();
    switch (status)
    {
        case OK:
            break;
        case FileNotFound:
            create_default_file();
            goto retry;
        case FileLocked:
            sleep(2);          /* Wait for other process to finish using it */
            goto retry;
        case FileAccessNotPermitted:
            do_dialog_box("ERROR: File permission problem.");
            exit(1);
        default:
            do_dialog_box("ERROR: An unknown error (%s) occurred while trying to write to the log file", system.getErrorString(status) );
            exit(1);
    }
Gigasoft wrote:It usually doesn't matter to an application how something went wrong - there is nothing it can do about it anyway.
That depends what the application is and how good the application is. A kernel shouldn't be designed for one specific application, and therefore should be design for a wide range of applications including applications that do want/need the error codes.

Who decides when a condition is an error anyway? Think about something this:

Code: Select all

    printf("Please remove the CD-ROM!");
    do {
        status = open("/dev/cd");
        switch(status) {
        OK:
            /* "OK" is an error (CD not removed) */
            close("/dev/cd");
        ....
    } while(status != NO_MEDIA);      /* "No media error" indicates everything is OK (CD-ROM successfully removed) */
Gigasoft wrote:As for receipt printers, they normally don't return error codes. Instead, they report their status when there is a change or when requested by the user, so it doesn't make sense for the system to make up an error code.
One of the reasons for kernel and device drivers to exist in the first place is to provide usable abstractions between applications and the hardware. For example, so that an application can just print something; without caring if it's using a colour ink jet printer, using a laser printer, having "print" redirected to remote service/printer on the network, having "print" redirected to a virtual device that actually generates a PDF file instead of printing anything, using a dot matrix receipt printer, etc (and without caring which manufacturer and model printer, or if the hardware itself handles postscript or bitmap data or only ASCII characters, or if it's connected via. USB or ethernet or parallel or serial). If the OS fails to provide useful abstractions then the OS is a worthless piece of crud.

Of course this abstraction means that you need to map various conditions (that may or may not be possible for specific printers) to a common set of error codes. For example, you might have "ERROR_NO_INK" or "ERROR_NETWORK_TIMEOUT" which don't make sense for a thermal/laser printer, but should still exist so that applications can be designed to support other types of printers without changes.
Gigasoft wrote:I am guessing that regardless of what the problem is, it is handled by displaying something like "Out of order - Please contact the staff" on the screen and halting.
I'm guessing you're talking about one specific application (e.g. a process that sits on top of the OS and handles an ATM machine), and forgot all about the OS underneath.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
rdos
Member
Member
Posts: 3276
Joined: Wed Oct 01, 2008 1:55 pm

Re: OS APIs without error codes

Post by rdos »

Gigasoft wrote:
switch (file.Error())
{
case FileNotFound: //...
case FileLocked: //...
case FileAccessNotPermitted: //...
}
I think //... is the important part here. It usually doesn't matter to an application how something went wrong - there is nothing it can do about it anyway. Either the hardware malfunctioned, or the programmer made a mistake. If the programmer made a mistake, he should have discovered it during testing. If a piece of the hardware has malfunctioned, it should be obvious to customer support after some investigation.
That's my point. You shouldn't surround every syscall with massive error decoding and recovery. Errors that are important instead should be possible to read-out on demand as device-status.

Of course, for the programmer, it could be useful to see why a function failed, but unless you work on a closed-source OS like Windows, you could always trace the syscall into kernel and see yourself why it failed, so there is no need for error-codes.
Gigasoft wrote:As for receipt printers, they normally don't return error codes. Instead, they report their status when there is a change or when requested by the user, so it doesn't make sense for the system to make up an error code. I am guessing that regardless of what the problem is, it is handled by displaying something like "Out of order - Please contact the staff" on the screen and halting.
Exactly. It is also required that the application know the status of the printer before the customer arrives, so just trying a printout and check the error status is not allowed in an EMV approved application. You need to know beforehand if a receipt can be printed or not.

And if the receipt printout fails, the receipt printer status after the printout should indicate some kind of error status that is more or less persistent.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: OS APIs without error codes

Post by bluemoon »

rdos wrote:
Gigasoft wrote:
switch (file.Error())
{
case FileNotFound: //...
case FileLocked: //...
case FileAccessNotPermitted: //...
}
That's my point. You shouldn't surround every syscall with massive error decoding and recovery. Errors that are important instead should be possible to read-out on demand as device-status.
This is common to do:

Code: Select all

#define SYSCALL_FAILED(code) ((code)<0)
if ( SYSCALL_FAILED(err = file.Error()) ) {
  I_dont_care_just_panic();
}

OR:


if ( SYSCALL_FAILED(err = file.Error()) ) {
  switch ( err ) {
  case FileNotFound:
      ...
  default:
      unknown_error();
  }
}

rdos
Member
Member
Posts: 3276
Joined: Wed Oct 01, 2008 1:55 pm

Re: OS APIs without error codes

Post by rdos »

Solar wrote:If you "correct" perfectly-good pseudocode into (pseudo-) source, don't selectively disable your brain (*), and at least use a somewhat-correct syntax, will you?

Code: Select all

    int rc = do( X );
    if ( rc == 0 )
        rc = do( Y );

    switch ( rc )
    {
        case 0:
            break;
        case a:
            handleError_A();
            break;
        case b:
            handleError_B();
            break;
        default:
            unexpectedError( rc );
            break;
    }
vs.

Code: Select all

    bool rc = do( X );
    if ( rc )
        rc = do( Y );

    if ( ! rc )
    {
        if ( isErrorA() )
            handleError_A();
        else if ( isErrorB() )
            handleError_B();
        else
            unexpectedError();
    }
Not so. I already gave you the correct code:

Code: Select all

    bool rc = do( X );
    if ( rc )
        rc = do( Y );
If you want to log the error you do it like this:

Code: Select all

    bool rc = do( X );
    if (!rc)
       log("X failed");
    if ( rc )
    {
        rc = do( Y );
        if (!rc)
            log("Y failed");
    }
The thing is, you never query error reason after the syscall. If you are paranoid about a syscall not failing, you check certain preconditions before the syscall, not after a failure. Compare this to the need to inform a customer that receipts cannot be printed before the transaction starts.

Why not an extreme example that should give you something to think about:
Persistence of transactions is achieved by saving them to disc. In order to be able to do any kind of transaction, it must be garanteed that a transaction can be saved and retrieved to/from disc. It is no good to think that I'll try a disc-write operation, and if it fails "I'll just panic". Your customer will get real mad at you because you dropped one of his/her transactions! Instead, you must be sure that appart from sudden hardware failures, writes of transactions will not fail, and restores will not fail.

For another example: If you want to create a new file, you first check that the directory path is present, that there exists no file that cannot be replace, and then go on to create the file. If the create fails after those checks, you can be pretty certain it is a persistent problem you cannot fix.
Last edited by rdos on Fri Apr 20, 2012 1:01 am, edited 2 times in total.
rdos
Member
Member
Posts: 3276
Joined: Wed Oct 01, 2008 1:55 pm

Re: OS APIs without error codes

Post by rdos »

bluemoon wrote: This is common to do:

Code: Select all

#define SYSCALL_FAILED(code) ((code)<0)
if ( SYSCALL_FAILED(err = file.Error()) ) {
  I_dont_care_just_panic();
}

OR:


if ( SYSCALL_FAILED(err = file.Error()) ) {
  switch ( err ) {
  case FileNotFound:
      ...
  default:
      unknown_error();
  }
}

Panic doesn't exist, neither do program stops. You cannot just stop an embedded application. If the receipt printer is malfunctioning, you inform the customer that receipts cannot be printed, and let the rest of the application run. Whatever fails, apart for hardware failures that you cannot live with, the application copes with what remaining functionality can be supported.
User avatar
Griwes
Member
Member
Posts: 374
Joined: Sat Jul 30, 2011 10:07 am
Libera.chat IRC: Griwes
Location: Wrocław/Racibórz, Poland
Contact:

Re: OS APIs without error codes

Post by Griwes »

rdos, you are wrong. Sometimes the application wants to show user a message, like in Brendan's version of my simple code. And wait, you want the user to have to trace the syscall to the kernel, even if the problem was a simple "file not found".

But, because you again don't even try to read those important parts of posts, where it's explained why polling different statuses simply fail to work (and we already showed two of them), I must assume you are just trolling and knowing that, I am leaving this thread.

rdos, some time ago all your topics were interested, but you turned into troll who just say "mine is better" and doesn't even spend time to carefully read what others are trying to tell you. RIP, interesting rdos started discussions.
Reaver Project :: Repository :: Ohloh project page
<klange> This is a horror story about what happens when you need a hammer and all you have is the skulls of the damned.
<drake1> as long as the lock is read and modified by atomic operations
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: OS APIs without error codes

Post by bluemoon »

Since when did we switch from talking error codes to program stop?
I did demonstrate that some kind of API interface let application to just use return code as boolean, or handle every error code; without another syscall or GetLastError()
rdos
Member
Member
Posts: 3276
Joined: Wed Oct 01, 2008 1:55 pm

Re: OS APIs without error codes

Post by rdos »

Griwes wrote:rdos, you are wrong. Sometimes the application wants to show user a message, like in Brendan's version of my simple code. And wait, you want the user to have to trace the syscall to the kernel, even if the problem was a simple "file not found".
Not the user, but the programmer. When I worked a lot on the Windows API, I sometimes got strange error-codes which made little sense. In such a scenario I'd wish I could have traced the syscall into kernel to see why it failed. Once the programmer understands why the code is wrong, it is fixed, and these error codes no longer are returned. I was talking about the convience of programmers, not a production-level function.
Griwes wrote:But, because you again don't even try to read those important parts of posts, where it's explained why polling different statuses simply fail to work (and we already showed two of them), I must assume you are just trolling and knowing that, I am leaving this thread.
I read them, but it appears that you didn't read mine. Very early in the thread I presented how the code would be layed-out, and it didn't include polling error-state after each syscall. I just posted a new message on this showing the proper implementation of error-code free code. You check error conditions before syscalls, not after they occur, if the reason matters.
User avatar
Griwes
Member
Member
Posts: 374
Joined: Sat Jul 30, 2011 10:07 am
Libera.chat IRC: Griwes
Location: Wrocław/Racibórz, Poland
Contact:

Re: OS APIs without error codes

Post by Griwes »

Sorry for double posting, but I noticed something I was, well, expecting. rdos, in post above my previous one, you mentioned embedded applications. But again, not mentioning embedded applications anywhere before. Once again, you are trying to convince up that embedded/rdos case is same as general, desktop case and that your OS is the only interesting case. Fine, develop it your way, but don't tell us that API that limites application developer by saying that "in good (embedded) application you don't need to know why something went wrong, but only whether it went wrong" (note: embedded, not general) is superior to error-code-orienten in general case, because it just isn't.

But reading what you just wrote taken all remaining hope from me. Your case is just hopeless.
Reaver Project :: Repository :: Ohloh project page
<klange> This is a horror story about what happens when you need a hammer and all you have is the skulls of the damned.
<drake1> as long as the lock is read and modified by atomic operations
rdos
Member
Member
Posts: 3276
Joined: Wed Oct 01, 2008 1:55 pm

Re: OS APIs without error codes

Post by rdos »

Griwes, I didn't say anything was superior. What method is best is up to anyone to decide. I just described how error-code less APIs could be developped and used, and I didn't say that everybody needs to adopt those. I just added to possible design choices of future OS developpers. If you don't like the concept, fine, don't use it. But don't just discard it because you don't understand it!
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: OS APIs without error codes

Post by Solar »

Griwes wrote:rdos, in post above my previous one, you mentioned embedded applications. But again, not mentioning embedded applications anywhere before.
That's not quite correct; he did mention "embedded" before. But even on an embedded system not returning the error code has no advantages and several disadvantages.

Not that he would ever admit that.
Every good solution is obvious once you've found it.
rdos
Member
Member
Posts: 3276
Joined: Wed Oct 01, 2008 1:55 pm

Re: OS APIs without error codes

Post by rdos »

Solar wrote:
Griwes wrote:rdos, in post above my previous one, you mentioned embedded applications. But again, not mentioning embedded applications anywhere before.
That's not quite correct; he did mention "embedded" before. But even on an embedded system not returning the error code has no advantages and several disadvantages.

Not that he would ever admit that.
It could have. I just admitted it. :lol:
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: OS APIs without error codes

Post by Solar »

rdos wrote:Griwes, I didn't say anything was superior.
rdos wrote:Traditional APIs (like DOS, Windows and *nix) are cluttered with error-codes, but is this really necesary? Isn't error-codes just a bagage from non-object oriented designs that are not really necesary?
You, sir, are a troll, a liar, and a very poor designer.

You didn't "add choices". You made a claim, we shot it down, and you're now trying to weazel out of it.
Last edited by Solar on Fri Apr 20, 2012 1:38 am, edited 1 time in total.
Every good solution is obvious once you've found it.
rdos
Member
Member
Posts: 3276
Joined: Wed Oct 01, 2008 1:55 pm

Re: OS APIs without error codes

Post by rdos »

Note that "embedded" can be extended to "web based" and "smart phone apps" as well. Most of these users are not programmers, and thus have no idea what to do about message boxes saying "file not found" or similar. :mrgreen:
Locked