pebbe / zmq4

A Go interface to ZeroMQ version 4

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Windows returns ERROR_BAD_FORMAT instead of EAGAIN

richjyoung opened this issue · comments

The recommended approach for handling errors fails on windows when specifically trying to catch EAGAIN. This appears to be due to platform-dependent behaviour of the syscall package, and instead appears as if there was an error trying to load the underlying ZeroMQ DLL.

Based on the recommended usage of zmq.Errno in errors.go, this is how I was attempting to catch EAGAIN:

zmq4/errors.go

Lines 66 to 80 in 4cb8523

Example usage:
switch AsErrno(err) {
case zmq.Errno(syscall.EINTR):
// standard system error
// call was interrupted
case zmq.ETERM:
// error defined by ZeroMQ
// context was terminated
}

switch zmq4.AsErrno(err) {
case zmq4.Errno(syscall.EAGAIN):
  // socket.RecvBytes(zmq4.DONTWAIT) returned no message
default:
  // Something else
}

This works fine on both linux and darwin platforms catching the native values of EAGAIN respectively, however on windows syscall.EAGAIN has been defined within the application error space, with a value of 536870918:
https://cs.opensource.google/go/go/+/refs/tags/go1.21.6:src/syscall/zerrors_windows.go;l=23

Based on https://learn.microsoft.com/en-us/cpp/c-runtime-library/errno-constants?view=msvc-170, EAGAIN is 11.

The problem that makes this very difficult to debug is that syscall.Errno(11).Error() on a windows platform is ERROR_BAD_FORMAT, or "An attempt was made to load a program with an incorrect format." - https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-

Given this package is a wrapper around the ZeroMQ library, and compiling/linking CGO on windows is not straightforward, ERROR_BAD_FORMAT would be expected to occur if there was something wrong in the toolchain or build process.

I don't think this is necessarily an error with this library, and I'm sure the maintainers of the syscall package had their reasons for the approach that was taken. However, can I suggest that either something is added to the documentation/examples, or the EAGAIN constant is redefined for all platforms within this library for the avoidance of confusion?