Search code examples
javascriptpromisefetch

reject() and return do not terminate execution


The following function is responsible to manage requests in a back-end service

const saveData = (body) => {

    // console.log("in save method body: ", JSON.stringify(body), "\n")
    return new Promise(function(resolve, reject) {
        const {fields, item} = body
        
        pool.query('Select count(1) as record_count from my_table where id= $1', [fields.id], (error, results)=>{
            if(error){
                reject(error)
                return
            }

            if(results && results.rows && results.rows[0].record_count > 0){
                console.log("in update fields are ", fields, "\n")
                updateData(fields).catch(error =>{
                    reject(error)
                    return
                })
            }
            else{
                console.log("in insert fields are \n", fields, "\r\n")
                insertData(fields).catch(error =>{
                    console.log("error is ", error)
                    reject(error)
                    return
                })          
            }            

            insertDataDetail(item).then().catch(error => {
                reject(error)
                return
            })
        })
        resolve("Save is done")
    })
}

insertData(..) returns Promise<QueryResult<R>>

I see console.log output but the function execution does not terminate then, the response seems successful but actually, it is not... What is wrong here?


Solution

  • The problem is that you are always resolving the promise. You have basically this:

    const saveData = () => {
      return new Promise((resolve, reject) => {
        // you call the query function which is async
    
        resolve("Save is done"); // this is always resolving the function before the query runs
    
      });
    }
    

    Instead you need to do this:

    const saveData = () => new Promise((resolve, reject) => {
      pool.query('query', [], (err, results) => {
        if (err) {
          return reject(err);
        }
    
        // whatever else you check
        return reject(new Error('something is not like I want it'));
    
    
        // everything is fine, continue
        return resolve(insertDataDetail(item));
    
      });
      // if you put something here it will run before the query is ran.
    });
    

    Mind the return reject | return resolve. Also mind that you can resolve returning another unresolved promise and if it fails it will be caught in the higher level catch from saveData.