-2

Good day I have a custom adonisjs command that pulls from an API.

async handle (args, options) {
    // Status 
    // Open = 1979

    // Get all jobs with open status.
    const pullJobController = new PullJobsFromJobAdderController;
    let token = await pullJobController.get_token();

    if(token){
        const jobs = await this._getOpenJobs('https://jobs/open-jobs', token , 1979);
    }
}

async _getOpenJobs(url, accessToken, status) {
        url = url + '?statusId=' + status
        const headers = {
            'Authorization': 'Bearer ' + accessToken
        }

        const options = {
            method: 'GET',
            url: url,
            headers: headers
        }

        return (await rp(options).then(function (result) {
            return {
                status: true,
                info: JSON.parse(result)
            }
            
        }).catch(function (error) {
            return {
                status: false
            }
        }));

    } // _getOpenJobs()

PullJobsFromJobAdderController

async get_token()
    {
        // This works if directly returning the token.
        // return "9ade34acxxa4265fxx4b5x6ss7fs61ez";  

        const settings = await this.settings();
        const jobAdderObject = new this.JobAdder(settings.jobadder['client.id'], settings.jobadder['client.secret'])
        const jobadderOauthObject = this.model('JobadderOauth');
        
        const accessInfo = await jobadderOauthObject.jobdderLatestAccess();

        let isAccessExpired = await this.checkAccessValidity(accessInfo.created_at);
        let accessToken = accessInfo.access_token;
        let apiEndpoint = accessInfo.api_endpoint;
        
        if(isAccessExpired === true){
            let refreshTokenInfo = await jobAdderObject.refrehToken(accessInfo.refresh_token)

            if (refreshTokenInfo.status === true) {
                let refreshTokenDetails = JSON.parse(refreshTokenInfo.info)
                accessToken = refreshTokenDetails.access_token
                apiEndpoint = refreshTokenDetails.api

                await jobadderOauthObject.create({
                    code: accessInfo.code,
                    access_token: refreshTokenDetails.access_token,
                    refresh_token: refreshTokenDetails.refresh_token,
                    scope: 'read write offline_access',
                    api_endpoint: refreshTokenDetails.api
                })
            }
        }
        
        return accessToken;
    } // get_token()

The function async get_token works as expected, it supplies me with a fresh token to be used by the adonisjs command. However it freezes after running the command.

But if I return the string token directly. The custom command handle() works as expected and terminates after running.

Scenario 1: (Directly returning the token string from PullJobsFromJobAdderController)

  1. I run my custom command "adonis pull:jobs" and it runs as expected displaying in the terminal the result of the pulled data from the api.
  2. Terminal is ready to accept another command. enter image description here

Scenario 2: (Comment out the directly returned string token from PullJobsFromJobAdderController)

  1. I run my custom command "adonis pull:jobs" and it runs as expected displaying in the terminal the result of the pulled data from the api.
  2. Terminal is not accepting commands until I press ctrl+c and terminate the current job/command. enter image description here

Perhaps I am missing something regarding async await calls.

Can someone point / help me to the right direction?

TIA

Hvel
  • 35
  • 8
  • 3
    *what "freezes after running" which "command"*? async/await never freezes - something, somewhere, that you are `await`ing on is returning a Promise that never resolves ... – Bravo Aug 17 '21 at 00:43
  • My apologies @Bravo, edited the question to explain both scenarios. – Hvel Aug 17 '21 at 01:04
  • _"Comment out the directly returned string token from PullJobsFromJobAdderController"_... it's hard to tell what you mean by this. Can you actually show these two scenarios as code changes? – Phil Aug 17 '21 at 01:07
  • i don't know what language that is, but it's not Javascript. perhaps it is TypeScript or CoffeeScript or something like that, idk, but not JS. – hanshenrik Aug 17 '21 at 01:07
  • 2
    @hanshenrik what makes you say that? At a cursory glance, it looks like plain old JavaScript to me – Phil Aug 17 '21 at 01:08
  • @hanshenrik - looks like plain ol' javascript to me - which part confuses you? – Bravo Aug 17 '21 at 01:09
  • @Phil ```async handle (args, options) {}``` is not valid syntax. it would be valid if it was ```async function handle (args, options) {}```, but it's not – hanshenrik Aug 17 '21 at 01:09
  • @hanshenrik ah, right. I just assumed OP cut that particular snippet out of an object or class. The `this._getOpenJobs` further down indicates the same – Phil Aug 17 '21 at 01:10
  • Should be `const pullJobController = new PullJobsFromJobAdderController();` (with brackets) surely? – see sharper Aug 17 '21 at 01:15
  • 1
    @seesharper - no - perfectly valid syntax – Bravo Aug 17 '21 at 01:15
  • @Bravo yes, PullJobsFromJobAdderController is my code and it works fine from another module. @Phil What I meant of commenting out is this line ```return "9ade34acxxa4265fxx4b5x6ss7fs61ez"; ``` (Scenario 2) – Hvel Aug 17 '21 at 01:16
  • Why not @Bravo? It's calling a constructor, or should be... – see sharper Aug 17 '21 at 01:19
  • 1
    Ah interesting, never noticed the parentheses were optional if there are no parameters. – see sharper Aug 17 '21 at 01:23
  • @Bravo I tried adding this to the handle(): ```try{ let token = await pullJobController.get_token(); console.log(token); if(token){ const jobs = await this._getOpenJobs('https://jobs/open-jobs', token , 1979); console.log(jobs); } } catch (err) { console.log(err); }``` how ever no errors were returned... still the terminal wont accept another command unless I manually terminate the running process. – Hvel Aug 17 '21 at 01:28
  • @Bravo does console.log(token); execute? yes it does. After getting the token from ```pullJobController.get_token()``` the next promise is ``` this._getOpenJobs()``` but i think it is resolving since it returns the API response, and in addition it works as expected if the ```pullJobController.get_token();``` returns a hard-coded token string. – Hvel Aug 17 '21 at 01:32
  • @Bravo does console.log(token); execute? Yes it does... If so, what is the code for this._getOpenJobs - did you write it? Yes I wrote it. Ill post it. – Hvel Aug 17 '21 at 01:37
  • Ok, so what is the code for `rp` function – Bravo Aug 17 '21 at 01:39
  • @Bravo it is a package from here: https://github.com/request/request-promise – Hvel Aug 17 '21 at 01:48
  • put some console.log's in that function to see how far along it's going ... I assume `console.log(jobs)` is NOT happening? – Bravo Aug 17 '21 at 01:51
  • @bravo console.log(jobs) work... i can see the response from the API. https://im.ge/i/NANZ9 its just that the terminal seems to freeze that i need to manually exit it to type another command – Hvel Aug 17 '21 at 01:53
  • 1
    oh, no idea what this `terminal` you keep going on about is, so the problem is somewhere else – Bravo Aug 17 '21 at 02:25
  • @Bravo I think it is from the async await since the terminal not terminating the job automatically only happens if i comment out ```return "9ade34acxxa4265fxx4b5x6ss7fs61ez";``` from ```PullJobsFromJobAdderController``` Thanks BTW @Bravo – Hvel Aug 17 '21 at 02:31
  • if jobs is logged, that's after the last await - so noting to do with async await – Bravo Aug 17 '21 at 02:50
  • will process.exit() after console.log(jobs) be enough? Since i just need a token from the ```pullJobController.get_token();``` and nothing else, since it returns a token i dont need it anymore. – Hvel Aug 17 '21 at 03:02

1 Answers1

0

I got it, for anyone else having this kind of problem with adonis commands: wrap the task inside your handle in a try... catch block then always have Database.close() and process.exit() in finally.

Hvel
  • 35
  • 8