redux-persist-sqlite-storage icon indicating copy to clipboard operation
redux-persist-sqlite-storage copied to clipboard

Missing error handling when 0 rows

Open parohy opened this issue 6 years ago • 3 comments

When we first time run app or upgrade app to a build where we introduced redux-persist-sqlite-storage, we are getting the following error Cannot read property 'value' of undefined

I have looked into this and noticed that in index.js at getItem you are trying to access rs.rows.item(0).value. In our case at first startup we have 0 rows. When refreshing-rerunning app it does not happen. All fine.

Because of this error, it skips our migration in redux persist from AsyncStorage.

How is this possible ? From within library code it seems this should not happen but it happens on our side. Is there a fallback default value to resolve there? I can submit a pull request on this.

parohy avatar Nov 13 '18 08:11 parohy

Hi @tomas-paronai ,

Thanks for reporting this issue. Please feel free to create PR related to this. I would be happy to have one.

Meanwhile, if you can share more detail on this error I would be happy to debug it.

prsn avatar Nov 13 '18 14:11 prsn

@prsn This is my suggestion for getItem. Notice callback in tx.executeSql:

function getItem(key, cb = noop) {
    return new Promise((resolve, reject) => {
      dbResolver.then( db => {
        db.transaction((tx) => {
          tx.executeSql(
            'SELECT value FROM store WHERE key=?', [key],
            (tx, rs) => {
              const item = rs.rows.item(0) || { value: {} };
              resolve(item.value);
              cb(null, item.value);
            },
            (tx, err) => {
              cb(err);
              reject('unable to get value', err);
            }
          );
        });
      }).catch(() => {
        reject(DB_CLOSED_MESSAGE);
      });
    });
  }

I am not sure about the default value there but can you elaborate what would be the ideal value in rs.rows.item(0).value ?

How to debug This happens, when there is no previous state stored in storage. So in example when you first time run the app with sqlite storage, at rehydrate it queries in sql for the state, but there is no previous state. At this point there is 0 rows. When the result callback is executed, you are trying to access rs.rows.item(0) in a 0 sized array, so thats undefined. Then you read rs.rows.item(0).value so that throws an exception in sqlite.core.js with the exact message that cannot read value of undefined.

parohy avatar Nov 14 '18 06:11 parohy

@tomas-paronai ,

Thanks for the input. I think default value depends on how redux-persist process that value. I mean if it is expecting an object then your approach is promising. I need to look at redux-persist first.

BTW which version of redux-persist you are using?

prsn avatar Nov 15 '18 02:11 prsn