Как обрабатывать ошибки с 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()