Capture errno before it can be clobbered, warn when no UDP address is valid, and give the reboot test timing headroom

This commit is contained in:
J. Nick Koston
2026-09-04 07:25:50 +02:00
parent 68d5968405
commit 9c4a08aaad
4 changed files with 11 additions and 5 deletions
@@ -43,11 +43,13 @@ bool AsyncClient::connect(const char *host, uint16_t port) {
}
if (socket_->setblocking(false) != 0) {
// A blocking connect()/read() would stall the whole loop
ESP_LOGE(TAG, "Failed to set nonblocking: errno %d", errno);
// Capture before the log and reset() below can clobber errno; a blocking
// connect()/read() would otherwise stall the whole loop
const int saved_errno = errno;
ESP_LOGE(TAG, "Failed to set nonblocking: errno %d", saved_errno);
socket_.reset();
if (error_cb_)
error_cb_(error_arg_, this, errno);
error_cb_(error_arg_, this, saved_errno);
return false;
}
+4
View File
@@ -19,6 +19,10 @@ void UDPComponent::setup() {
}
this->sockaddrs_.push_back(saddr);
}
if (!this->addresses_.empty() && this->sockaddrs_.empty()) {
// Sending would be a silent no-op; surface the misconfiguration
this->status_set_warning(LOG_STR("no valid addresses"));
}
// set up broadcast socket
if (this->should_broadcast_) {
this->broadcast_socket_ = socket::socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
@@ -2,6 +2,6 @@ esphome:
name: api-reboot-test
host:
api:
reboot_timeout: 0.5s # Very short timeout for fast testing
reboot_timeout: 2s # Headroom to connect and authenticate a client first
logger:
level: DEBUG
+1 -1
View File
@@ -59,6 +59,6 @@ async def test_api_reboot_timeout_after_authenticated_disconnect(
async with api_client_connected() as client:
await client.device_info()
try:
await asyncio.wait_for(reboot_future, timeout=2.0)
await asyncio.wait_for(reboot_future, timeout=5.0)
except TimeoutError:
pytest.fail("Device did not reboot within expected timeout")