Node Sqlite3 Errors

913 Views Asked by At

I'm using the sqlite3 package in node and beginning to flush out my REST API. I've decided to create a promise wrapper around the DB calls and in the controllers, use async/await to call those functions and set that return value to a variable. Then, check the variable and set a response object. For the success cases it's working well, found a thing and set the response. Problem is, in SQLITE3 I'm having a hard time checking for errors. I have a basic check for undefined in the DB service which does throw an error if it encounters an error, but that error goes immediately to the CATCH section of the controller and doesn't allow me to wrap it in an API response I'd like to define. These are separate files (controller vs. service). I'm not finding a lot of helpful information on error checking for sqlite3, it's sparse out there. Ideally the service would throw an error which I could then wrap into a standardized response object and send.

------ LOCATION

const getById = async (req, res, next) => {
    response = {};
    try {
        let location = await getLocationById(req.params.id); // <-- IF NO VALUE FOUND, location IS nothing
        if (error) { // <----- THIS IS WHERE I'D LIKE TO CHECK FOR ERRORS.
            response.status = 404;
            response.message = 'Error attempting to get location';
        } else {
            response.status = 200;
            response.message = 'Success';
            response.data = location;
        }
        res.json(response);
    } catch (error) {
        res.json(response);
    }
};

------------ SERVICE

const getLocationById = (id) => {
    return new Promise((resolve, reject) => {
        let sql = 'SELECT * FROM Locations WHERE id = ?;';
        db.get(sql, [id], (error, location) => {
            if (location !== undefined) {
                resolve(location);
            } else {
                reject(new Error('Error attempting to get location by id'));
            }
        });
    });
};
1

There are 1 best solutions below

5
On BEST ANSWER

You just need to wrap the call to getLocationById() in another try/catch. From there you can decide if you want to wrap or raise the error. If you don't have additional code to add that might throw an error you can remove the outer try/catch. More explanation and suggestions in inline comments:

const getLocationById = (id) => {
  return new Promise((resolve, reject) => {
    const sql = "SELECT * FROM Locations WHERE id = ?;";
    db.get(sql, [id], (error, location) => {
      // check for an error from the db here
      if (error) return reject(error);
      // check for an empty result here and throw your own error
      if (!location) {
        // set a property so we can tell that it wasn't a db error just not found
        const myError = new Error("Error attempting to get location by id");
        myError.notFound = true;
        return reject(myError);
      }
      // otherwise resolve the result
      return resolve(location);
    });
  });
};
const getById = async (req, res, next) => {
  // use const since it is not reassigned, only properties are changed
  const response = {};
  try {
    // code here that might throw an exception
    try {
      // use const if you aren't going to reassign `location`
      const location = await getLocationById(req.params.id); 
      
      // we were able to load the location if we get here
      response.status = 200;
      response.message = "Success";
      response.data = location;
    } catch (error) {
      // maybe check to see if we want to wrap or raise the error
      // maybe call console.log(error) to see the contents
      const doWeWantToWrapTheError = somethingToCheckTypeEtc(error);
      if (doWeWantToWrapTheError) {
        if (error.notFound) {
          // no db errors, just not found
          response.status = 404;
        } else {
          // some kind of db error so set to "internal server error"
          response.status = 500;
        }
        response.message = "Error attempting to get location";
      } else {
        // raise the error to the outer try/catch
        throw error;
      }
    }
    // code here that might throw an exception
    return res.json(response);
  } catch (unexpected) {
    // some other error occurred that was not caught above (unlikely)
    // maybe call console.log(unexpected) to see the contents
    response.error = unexpected.message;
    return res.json(response);
  }
};