Hacker News new | past | comments | ask | show | jobs | submit login

This is how I imagine the error code looks. How else can you even return the wrong error?

```c#

public class FooError {

public Message(){

  //TODO: I copy pasted this from somewhere else. I still need to update to a meaningful message

  return "this is a BarError"

  }
} ```



The code which outputs the error message is probably getting it from GetLastError() or similar (the Windows equivalent to POSIX's errno). But meanwhile, some error handling code has called some library functions (probably to restore the system to a sane state), and one of these library functions accidentally overwrote the global per-thread "last error" variable. That is, the error in the error handling routine would simply be a lack of doing a "saved = GetLastError()" at the start and then a "SetLastError(saved)" at the end.

This kind of mistake is very common when dealing with GetLastError() or errno, since most library functions you might call while handling an error do not overwrite these values... until something in one of them fails (sometimes even a non-fatal error which is handled internally by them) and overwrites that per-thread variable.


Yeah that's almost certainly the issue.

Last year I had to debug a Windows issue that caused the following: we get back a struct from the Windows API that contains an HRESULT style error code, and also a string error message in case of error. Printing the string revealed that it started with the error code in hex, so we just logged the string. As part of a workaround for another Windows bug we had to check the error code for a specific value and do something different.

Eventually we got a report from a Windows machine in the wild where the code seemed to be doing something impossible: the log indicated the error code we looked for was being returned, yet, the code didn't take the conditional path that checked for it. After a lot of head scratching we realised there was only one possibility: the error code printed in the error message and the error code returned in the structure didn't actually match. Sure enough that turned out to be the case. Somehow Microsoft had generated the textual version of the error successfully, and then the machine readable error code had been replaced with something else before it was returned. The fix was to compare against both the HRESULT and the stringified form.

Naturally, this error only occurred on some Windows installs and not others for no obvious reason. The core OS seems to have tech debt issues so severe that it's basically impossible to verify even for app developers - you can do everything right, test it all carefully, and your code will still blow up in the wild in an undocumented fashion because no two Windows installs are quite alike, even (perplexingly) for fresh out-of-the-box installs that appear to be the same version. At this point even Linux is more consistent than Windows 10 is. I can't imagine how painful it must be to work on Windows deployments at Microsoft. The install base has become so inconsistent that they're pretty much guaranteed to trash people's systems with every change they make by now.


I remember one bit of customer code where I needed to pass a BSTR string into a function. I constructed it using CComBSTR without considering that the destructor calls SetLastError. I could see the call failing but the only information I got back was ERROR_SUCCESS.


In C/C++ land, errors are often mapped to const size_t int values. Whether it's an enum or just a list of "codes". In this case, I suspect (like OpenGL) it's just a giant list of codes defined as "extern const uint32_t MY_SUPER_ERROR = 0x0001" and some other part of the code has defined the same value to another error type. Then it's trying to value match and give a human readable value (0x001) but based on the matched value (0x0001 becomes 0x1000) because MY_SUPER_ERROR is 0x1000 in some other part of the code. This happens when people in C/C++ land follow this logic:

Lib Guy 1: "I need an error.h to store all my errors to make it easy for me"

Lib Gal 2: "I need an error.h to store all of my error values so I can just use type names like a boss"

Exe Guru 1: "Which <error.h> is this?"

The other option is that an error was thrown inside error handling code which threw an error and was unhandled, throwing an error generically at the base.


0x80070643 is ERROR_INSTALL_FAILURE, so yeah basically somebody clobbered the error code in some installation routine. It's in winerror.h, according to https://learn.microsoft.com/en-us/windows/win32/debug/system...


“What’s a null?”

“Well, it’s the absence of a value, or 0, or nullptr, or…”

“Forget it, you’re insane.”

- My son.


My guess is that part of the error handling is appending to the logs. Maybe something like (I can't remember C#, so thinking about Java instead):

    try{
      try{
        windows_update_function_that_saves_to_disk();
      }catch(DiskSpaceException e){
        DiskLogger.log(e.printStackTrace()); // itself tries to save to disk
        System.err.println(e.printStackTrace());
      }
    }catch(GenericException e){
      // something went really badly wrong, generic error
    }


The logic in the `catch` block could be complex enough that they got an if/else backwards or something like that. E.g., they could catch an exception and then have the body of the `catch` return six different error messages based on details about the exception, system status, etc.


"Oops, something went wrong"




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: