Skip to content

When using an async resolver which uses the fetch method to access an external endpoint the running flow is immediately interrupted #42

@andreadipalma

Description

@andreadipalma

When using an async resolver which uses the fetch method to access an external endpoint the running flow is immediately interrupted and returns the control to the caller function without completing the tasks.

export function query_similar(query: string, filters: string) {
    return new Promise(async (resolve, reject) => {
        try {
            /* Call Clean API on the Front End API to reload the definition */
            const similar = "https://query-data.azurewebsites.net/api/similar?" + new URLSearchParams(
            {
                'op': "query",
                'query': query,
                "max_results": "10"
            });

           let response = await fetch(similar, {
                method: "GET",
                headers: {
                    "Content-Type": "application/json",
                }
            });

           const body = await response.json();
            
            if (body === undefined) {
                throw new Error(`Failed to call function: ${response.statusText}`);
            }
            resolve(body);
        } catch (error) {
            reject(error); // Reject the promise if an error occurs
        }
    });                           
}

async nlp_rank(item_id_field: string, records: any[], user_message:string) {
    if (isNotNull(records) && records.length > 0 && isNotNull(user_message)) {
      try {
        let id_list:string = records.map(record => record[item_id_field]).join(",");
        // call api to retrieve similarity ranking 
        const ranked_records = await query_similar(user_message, id_list);
        // merge arrays by document id
        let out_records = records.map((record, i) => Object.assign({}, record, ranked_records));     
        return out_records;
      } catch (error) {
        return;
      }
    }
  }

// This is the resolver class
export class ContentRank {
  async exec(params: ValueMap, context:ValueMap) {
    // simplified code

    records = await nlp_rank(item_id_field, input_records.records, userProfile.message);
    return { results: { records: records } };
  }
}

let results = await FlowManager.run(
        // The flow spec
        ret.strategy,          
        // The parameters
        ret.params,
        // The expected results
        [ out ],          
        // The resolvers mapping
        {
          load: Load as unknown as TaskResolverExecutor,
          filter: Filter as unknown as TaskResolverExecutor,
          contentrank: ContentRank as unknown as TaskResolverExecutor,
          similarrank: SimilarRank as unknown as TaskResolverExecutor,
          top: Top as unknown as TaskResolverExecutor,
          sort: Sort as unknown as TaskResolverExecutor,
          merge: Merge as unknown as TaskResolverExecutor
        },
        { webAPI: this.context, registry: this.registry, userManager},
      );

Without the async resolver the workflow completes correctly, I suspect I'm doing some mistake with await async into the chain of function calls but really struggling to find where it could be.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions