Defer nvs_open warning instead of dropping it

Stash the err code in a static and emit ESP_LOGW lazily from the first
make_preference() call (which runs after Logger::pre_setup() at
EARLY_INIT priority), so the diagnostic stays visible without
dereferencing global_logger before it is set.
This commit is contained in:
J. Nick Koston
2026-04-27 09:53:40 -05:00
parent 7770190f55
commit 98f250b62c
+13 -2
View File
@@ -18,6 +18,12 @@ struct NVSData {
static std::vector<NVSData> s_pending_save; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
// open() runs from app_main() before the logger is initialized, so any failure
// must be deferred until after global_logger is set. This is emitted from the
// first make_preference() call, which runs from the generated setup() after
// log->pre_setup() has run at EARLY_INIT priority.
static esp_err_t s_open_err = ESP_OK; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
bool ESP32PreferenceBackend::save(const uint8_t *data, size_t len) {
// try find in pending saves and update that
for (auto &obj : s_pending_save) {
@@ -70,13 +76,14 @@ bool ESP32PreferenceBackend::load(uint8_t *data, size_t len) {
}
void ESP32Preferences::open() {
// Can't use ESP_LOG... in this function because it is called before the logger is initialized
// Runs from app_main() before the logger is initialized; any logging here
// must be deferred. See s_open_err and make_preference() below.
nvs_flash_init();
esp_err_t err = nvs_open("esphome", NVS_READWRITE, &this->nvs_handle);
if (err == 0)
return;
// nvs_open failed, erasing NVS
s_open_err = err;
nvs_flash_deinit();
nvs_flash_erase();
nvs_flash_init();
@@ -88,6 +95,10 @@ void ESP32Preferences::open() {
}
ESPPreferenceObject ESP32Preferences::make_preference(size_t length, uint32_t type) {
if (s_open_err != ESP_OK) {
ESP_LOGW(TAG, "nvs_open failed: %s - erased NVS", esp_err_to_name(s_open_err));
s_open_err = ESP_OK;
}
auto *pref = new ESP32PreferenceBackend(); // NOLINT(cppcoreguidelines-owning-memory)
pref->nvs_handle = this->nvs_handle;
pref->key = type;