Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper way to avoid Spotify errors #2

Open
carcot opened this issue Nov 5, 2021 · 5 comments
Open

Proper way to avoid Spotify errors #2

carcot opened this issue Nov 5, 2021 · 5 comments

Comments

@carcot
Copy link

carcot commented Nov 5, 2021

Every so often when my program calls buddyList.getFriendActivity(accessToken) I get the error

/.../node_modules/node-fetch/lib/index.js:273
				return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json'));
				                           ^
FetchError: invalid json response body at https://open.spotify.com/get_access_token?reason=transport&productType=web_player reason: Unexpected token u in JSON at position 0
    at /.../node_modules/node-fetch/lib/index.js:273:32
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async getFriendActivity (/.../fa.js:55:29)
    at async main (/.../fa.js:11:30) {
  type: 'invalid-json'
}

and I would like to avoid having this error crash my program. I have tried various workarounds, but I am not a JS expert and was hoping you might be able to help. I thought that following code should work, but it still doesn't work reliably.

async function getFriendActivity () {
    const spDcCookie = 'my cookie is here'

    const { accessToken } = await buddyList.getWebAccessToken(spDcCookie)

    var friendActivity = false
    while (!friendActivity) {
        try {
            friendActivity = await fulfillWithTimeLimit(1000, buddyList.getFriendActivity(accessToken), false)
        } catch {
            friendActivity = false
        }
    }

    return friendActivity
}

where fulfillWithTimeLimit(timeLimit, task, failureValue) is

//  https://medium.com/swlh/set-a-time-limit-on-async-actions-in-javascript-567d7ca018c2
async function fulfillWithTimeLimit(timeLimit, task, failureValue) {
    let timeout
    const timeoutPromise = new Promise((resolve, reject) => {
        timeout = setTimeout(() => {
            resolve(failureValue)
        }, timeLimit)
    })

    const response = await Promise.race([task, timeoutPromise])
    if (timeout) {   //  the code works without this but let's be safe and clean up the timeout
        clearTimeout(timeout)
    }

    return response
}

Do you have any suggestions on how I can make this work reliably?

@valeriangalliat
Copy link
Owner

Hey! It looks like the exception is happening at the getWebAccessToken for which you don't have a catch block, which is why the function fails :)

You should add a try/catch around this, and probably put another while loop around it if you want to keep retrying when it getWebAccessToken fails too.

I would also recommend that you add some kind of delay (maybe even exponential delay) between each retry to avoid hammering the Spotify API if something goes wrong. Cheers!

@carcot
Copy link
Author

carcot commented Nov 5, 2021

Oh, I see now. Thank you!

Does the accessToken need to be fetched again each time before the call to getFriendActivity(accessToken)? (I.e., does it change?)

Thanks for you help.

@valeriangalliat
Copy link
Owner

If you do const token = await buddyList.getWebAccessToken(spDcCookie) and you console.log(token) you'll see other fields returned by Spotify including the expiry of the token, I think it's something like an hour? So based on that you should be able to reuse the same token during that period =)

@carcot
Copy link
Author

carcot commented Nov 6, 2021

I implemented your previous suggestion and so far so good! I'll let you know after I've had more time to test it. Thanks for your help.

@iCrowd
Copy link

iCrowd commented Mar 10, 2022

Hey since I had to set up my windows again i get this error too. Before it worked just fine, I never had any problems.

It looks like this for me but since i have no idea what im doing how can I avoid this error?

const buddyList = require('spotify-buddylist')

async function main () {
  const spDcCookie = 'my cookie here'
  const { accessToken } = await buddyList.getWebAccessToken(spDcCookie)
  const friendActivity = await buddyList.getFriendActivity(accessToken)
  
  console.log(new Date())
  console.log(JSON.stringify(friendActivity, null, 2))
}

setInterval(main, 60000);

clearInterval(main);
main()
  .catch(err => {
    console.error(err)
    process.exit(1)
  })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants