diff --git a/lib/PsychicMqttClient/src/PsychicMqttClient.cpp b/lib/PsychicMqttClient/src/PsychicMqttClient.cpp index 1f94ad82..c91f3a50 100644 --- a/lib/PsychicMqttClient/src/PsychicMqttClient.cpp +++ b/lib/PsychicMqttClient/src/PsychicMqttClient.cpp @@ -726,17 +726,30 @@ void PsychicMqttClient::_onPublish(esp_mqtt_event_handle_t &event) void PsychicMqttClient::_onError(esp_mqtt_event_handle_t &event) { ESP_LOGI(TAG, "MQTT_EVENT_ERROR"); - if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) - { - log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err); - log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err); - log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno); - ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno)); + esp_mqtt_error_codes_t *err = event->error_handle; - for (uint8_t i = 0; i < _onErrorUserCallbackCount; ++i) - { - _onErrorUserCallbacks[i](*event->error_handle); - } + if (err->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) + { + log_error_if_nonzero("reported from esp-tls", err->esp_tls_last_esp_err); + log_error_if_nonzero("reported from tls stack", err->esp_tls_stack_err); + log_error_if_nonzero("captured as transport's socket errno", err->esp_transport_sock_errno); + ESP_LOGI(TAG, "Last errno string (%s)", strerror(err->esp_transport_sock_errno)); + } + else if (err->error_type == MQTT_ERROR_TYPE_CONNECTION_REFUSED) + { + // Broker accepted the socket but rejected the MQTT CONNECT. The return + // code distinguishes auth failures (4=bad user/pass, 5=not authorized) + // from server unavailable (3), protocol mismatch (1), and client-id + // rejection (2) — the key signal for diagnosing a server-side lockout. + ESP_LOGE(TAG, "Connection refused, return code 0x%x", err->connect_return_code); + } + + // Forward every error type to the user callbacks. Previously only transport + // errors were forwarded, so CONNACK rejections (CONNECTION_REFUSED) were + // silently dropped and never surfaced to the application. + for (uint8_t i = 0; i < _onErrorUserCallbackCount; ++i) + { + _onErrorUserCallbacks[i](*err); } } diff --git a/src/helpers/bridges/MQTTBridge.cpp b/src/helpers/bridges/MQTTBridge.cpp index 3c3ac91f..9dcf5561 100644 --- a/src/helpers/bridges/MQTTBridge.cpp +++ b/src/helpers/bridges/MQTTBridge.cpp @@ -1139,7 +1139,14 @@ void MQTTBridge::initSlotClients() { _slots[index].last_tls_stack_err = error.esp_tls_stack_err; _slots[index].last_sock_errno = error.esp_transport_sock_errno; _slots[index].last_error_time = millis(); - if (error.esp_tls_last_esp_err != 0 || error.esp_tls_stack_err != 0 || error.esp_transport_sock_errno != 0) { + if (error.error_type == MQTT_ERROR_TYPE_CONNECTION_REFUSED) { + // Broker rejected the MQTT CONNECT itself — not a transport failure. + // return code: 1=protocol, 2=client-id rejected, 3=server unavailable, + // 4=bad username/password, 5=not authorized. Codes 3/4/5 point at a + // server-side lockout or auth problem rather than the network. + MQTT_DEBUG_PRINTLN("MQTT%d connection refused by broker (return code=%d)", + index + 1, (int)error.connect_return_code); + } else if (error.esp_tls_last_esp_err != 0 || error.esp_tls_stack_err != 0 || error.esp_transport_sock_errno != 0) { MQTT_DEBUG_PRINTLN("MQTT%d error: tls=%d, tls_stack=%d, sock=%d, type=%d", index + 1, error.esp_tls_last_esp_err, error.esp_tls_stack_err, error.esp_transport_sock_errno, error.error_type);