Closed egor-tensin closed 8 years ago
Thanks for the report, Although I'm not quite sure about using SetLastError
here. I think we should instead use maperrno_func
to convert the error instead of maperrno
and pass it the error code directly.
That should be much faster than going through the TLS for an error we already have. However I wonder If this error code passed to the function is always filled in. Have you checked to see with an API call that does call SetLastError
?
I have, see e.g. https://github.com/egor-tensin/win32-issue-setlasterror. About the error code not being filled in, do you mean that somebody might pass some kind of a dumb value to failWith
? According to a quick grep
, nobody does.
BTW, I think that calling SetLastError
prior to maperrno
is beneficial for one more reason: FormatMessage
(used in getErrorMessage
) might also call SetLastError
, erasing the value before the call to maperrno
.
I agree that some kind of an error code conversion function would be much better than the current mechanism (which is quite error-prone), I just tried to introduce a minimal fix.
Sorry, I don't completely follow, I don't see anything in that repository except a test that catches a file not found exception?
What I meant before is, why call SetLastError
at all when all we do with the error code is pass it to maperrno_func
anyway in maperrno
. We might as well directly call maperrno_func
instead of maperrno
passing it the error code directly. getErrorMessage
also takes an explicit error code.
Unless I am misunderstanding something?
Yes, right. Please disregard my previous inquiries. The reason for my confusion was that I haven't even noticed that maperrno
is just a tiny wrapper around maperrno_func
, which is of course much better. Can you please take a look at the current version? Seems like it properly solves every problem.
I was rambling about getErrorMessage
because the underlying FormatMessageW
can call SetLastError
if used incorrectly, which would erase the value to be later used by maperrno
, but the current version renders that concern obsolete.
Great! thanks!. Added a minor nit. Could you update and add a small entry to the changelog and then I'll merge.
Added a changelog entry.
Thanks for the report and fix!
I've discovered that
failWith
doesn't work perfectly withIOError
. In particular, it appears that it doesn't provide properIOErrorType
. GetLastError()-to-errno conversion aside, one issue seems to be that some WinAPI functions don't actually callSetLastError
, returning an error code instead. In those cases, whenmaperrno
is called, it converts a junk value returned byGetLastError
. I added a call toSetLastError
just before the call tomaperrno
so that it converts the actual error code returned by an API call.I bumped into this while trying to detect when
regOpenKey
fails because of the key missing. I usedisDoesNotExistError
for this, only to discover that it doesn't work. I've created two repositories to demonstrate the issue and the fix:(The code is identical in both. I wanted to somehow make two source files instead of the full-fledges repos, but my cabal/stack-fu is not on par.)
I realize that this fix is lacking proper verification and testing; I'm just hoping somebody more competent will take a look.