Как обрабатывать ошибки с JZMQ?

Документация дляSocket#recv() гласит:

Возвращает: [...] ноль при ошибке.

Как я могу сказать, в чем была ошибка? Я хочу справиться EAGAIN в частности.

2 ответа

Решение

У меня здесь очень ограниченные знания, но, судя по всему, ответ может быть следующим:
"Если Socket#recv() возвращает ноль и нет ZMQException был брошен, произошла ошибка EAGAIN."

Я следовал за вызовами методов и пришел к do_read в Socket.cpp где это становится интересным в строке 83:

rc = zmq_recv (socket, message, flags);
int err = zmq_errno();
if (rc < 0 && err == EAGAIN) {
    rc = zmq_msg_close (message);
    err = zmq_errno();
    if (rc != 0) {
        raise_exception (env, err);
        return NULL;
    }
    return NULL;
}
if (rc < 0) {
    raise_exception (env, err);
    rc = zmq_msg_close (message);
    err = zmq_errno();
    if (rc != 0) {
        raise_exception (env, err);
        return NULL;
    }
    return NULL;
}
return message;

Я прочитал здесь, что если что-то пойдет не так, вы получите ZMQException в Java, если ошибка не была EAGAIN а также zmq_msg_close не ошибается (я не уверен, что zmq_msg_close делает, но я предполагаю, что это редко идет не так, как надо).
Но у меня нет среды, чтобы проверить это, и я также не очень понимаю, как raise_exception работает (источник в util.cpp): что происходит, если два исключения вызываются / генерируются в одном и том же пути кода (например, когда err это не EAGAIN и rc < 0) и вы можете поймать только одно исключение времени выполнения в Java?

Кстати, поддержка этого кода ошибки EAGAIN была добавлена ​​в этот коммит 15 мая 2015 года.

Исходный код:

    /**
         * Receive a message.
         *
         * @return the message received, as an array of bytes; null on error.
         */ 
        public final byte[] recv()
        {
            return recv(0);
        }

        /**
         * Receive a message.
         *
         * @param flags
         *            the flags to apply to the receive operation.
         * @return the message received, as an array of bytes; null on error.
         */
        public final byte[] recv(int flags)
        {
            zmq.Msg msg = base.recv(flags);

            if (msg != null) {
                return msg.data();
            }

            mayRaise();
            return null;
        }

        private void mayRaise()
        {
            int errno = base.errno();
            if (errno != 0 && errno != zmq.ZError.EAGAIN) {
                throw new ZMQException(errno);
            }
        } 

так что вы можете изменить функции recv(int flags) и mayRaise()

Другие вопросы по тегам