API change for company ID? | Tools & Userscripts | TORN
API change for company ID?
    • SirEdge [2609907]
    • Role: Civilian
    • Level: 80
    • Posts: 3220
    • Karma: 2605
    • Last Action: 1 hour
      • 0
    • Reason:
      Are you sure you want to report this post to staff?
      Cancel
    Thread created on 14:54:07 - 27/06/22 (1 month ago)
    |
    Last replied 20:22:47 - 27/06/22 (1 month ago)
    Was there recently a change in how the Job object is passed for people that don't have a job?  My script suddenly had the fail rate soar and stepping through it and comparing with the  API Page helped me see that the job object isn't showing up at all in this case.

    Anyone familiar with javascript that can help me adjust my error handling to handle the object not returning? Right now it just fails if the whole request doesn't work. I'm not very good with Javascript, to be honest, but it has been working for many months.
    Last edited by SirEdge on 14:54:17 - 27/06/22

    88325a84-98c2-374d-2609907.gif

    • SirEdge [2609907]
    • Role: Civilian
    • Level: 80
    • Posts: 3220
    • Karma: 2605
    • Last Action: 1 hour
      • 0
    • Reason:
      Are you sure you want to report this post to staff?
      Cancel
    Posted on 15:17:01 - 27/06/22 (1 month ago)
    Post link copied to clipboard Copy post link
    Opened a defect for this after finding 7 other examples that returned a job object for players that don't have a job: Link
    Last edited by SirEdge on 15:19:26 - 27/06/22

    88325a84-98c2-374d-2609907.gif

    • SVD_NL [2363978]
    • Role: Civilian
    • Level: 87
    • Posts: 1087
    • Karma: 1193
    • Last Action: 10 hours
      • 0
    • Reason:
      Are you sure you want to report this post to staff?
      Cancel
    Posted on 16:49:57 - 27/06/22 (1 month ago)
    Post link copied to clipboard Copy post link

    SirEdge [2609907]

    Was there recently a change in how the Job object is passed for people that don't have a job? My script suddenly had the fail rate soar and stepping through it and comparing with the API Page helped me see that the job object isn't showing up at all in this case.

    Anyone familiar with javascript that can help me adjust my error handling to handle the object not returning? Right now it just fails if the whole request doesn't work. I'm not very good with Javascript, to be honest, but it has been working for many months.
    To account for these kinds of errors i usually use a combination of optional chaining and checking if it exists.

    Be careful though, as this can cause some difficult to trace errors.

    You'd end up with something like this:

    const companyId = apiCall.job?.company_id;
    if (!companyId) {
    //handle the error
    }
    //Rest of code

    It depends a bit on your specific situation of course, above works fine if you just need one value but gets very messy if you want to get multiple values, or want to pass the job object to a function.

    If you need multiple values it is often cleaner to check for the existence of the job object:

    const job = apiCall.job
    if (!job) {
    //Handle error
    }

    //Rest of code

    You can also use if (job) {...} Else {...} But i like the above way better because it reduces the amount you need to indent your code.


    Because of how weird the API can be sometimes i usually have loads of safeguards like that in place, just try to think of which method will let you catch those weird errors as early as possible.

    • SirEdge [2609907]
    • Role: Civilian
    • Level: 80
    • Posts: 3220
    • Karma: 2605
    • Last Action: 1 hour
      • 0
    • Reason:
      Are you sure you want to report this post to staff?
      Cancel
    Posted on 18:27:55 - 27/06/22 (1 month ago)
    Post link copied to clipboard Copy post link

    SVD_NL [2363978]

    To account for these kinds of errors i usually use a combination of optional chaining and checking if it exists.

    Be careful though, as this can cause some difficult to trace errors.

    You'd end up with something like this:

    const companyId = apiCall.job?.company_id;
    if (!companyId) {
    //handle the error
    }
    //Rest of code

    It depends a bit on your specific situation of course, above works fine if you just need one value but gets very messy if you want to get multiple values, or want to pass the job object to a function.

    If you need multiple values it is often cleaner to check for the existence of the job object:

    const job = apiCall.job
    if (!job) {
    //Handle error
    }

    //Rest of code

    You can also use if (job) {...} Else {...} But i like the above way better because it reduces the amount you need to indent your code.


    Because of how weird the API can be sometimes i usually have loads of safeguards like that in place, just try to think of which method will let you catch those weird errors as early as possible.
    First, I should say that I am not a programmer (took 1 year of CS in uni and didn't do well).  I understand many OO concepts from my classes, but I'm not very good at using them.  I am, however, really good with spreadsheets.

    When I wrote the javascript to pull the data, I wanted to make my script flexible to easily add or remove fields (such as for the active competition). So my script actually has no idea what object it is looking for- I use two fields per column in the spreadsheet to spell out the object and attribute in question and dump out all of the values are part of a ginormous table, where I can use spreadsheet functions to process it.

    And yes, all of the attributes of the base player object have to be called before any on child objects, because it switches from blank parent object to populated parent object and when it goes blank again, that is the signal that the last field from the pull has been reached.

    So the place that leaves me is there isn't any logic specific to individual objects. I could add some, but I admit I would prefer to find a solution that debugs records as either 1) attributes not in a child object or 2) attributes of child objects to now make it over complicated.

    Maybe I'm kidding myself and I just need to do it. Just wanted to see if someone here had a slick idea on how it could be done in my existing logic framework before I go redesigning (and breaking, maybe followed by fixing) the whole thing.

    Thanks!
    Last edited by SirEdge on 18:28:03 - 27/06/22

    88325a84-98c2-374d-2609907.gif

    • SVD_NL [2363978]
    • Role: Civilian
    • Level: 87
    • Posts: 1087
    • Karma: 1193
    • Last Action: 10 hours
      • 0
    • Reason:
      Are you sure you want to report this post to staff?
      Cancel
    Posted on 20:06:00 - 27/06/22 (1 month ago)
    Post link copied to clipboard Copy post link

    SVD_NL [2363978]

    To account for these kinds of errors i usually use a combination of optional chaining and checking if it exists.

    Be careful though, as this can cause some difficult to trace errors.

    You'd end up with something like this:

    const companyId = apiCall.job?.company_id;
    if (!companyId) {
    //handle the error
    }
    //Rest of code

    It depends a bit on your specific situation of course, above works fine if you just need one value but gets very messy if you want to get multiple values, or want to pass the job object to a function.

    If you need multiple values it is often cleaner to check for the existence of the job object:

    const job = apiCall.job
    if (!job) {
    //Handle error
    }

    //Rest of code

    You can also use if (job) {...} Else {...} But i like the above way better because it reduces the amount you need to indent your code.


    Because of how weird the API can be sometimes i usually have loads of safeguards like that in place, just try to think of which method will let you catch those weird errors as early as possible.

    SirEdge [2609907]

    First, I should say that I am not a programmer (took 1 year of CS in uni and didn't do well). I understand many OO concepts from my classes, but I'm not very good at using them. I am, however, really good with spreadsheets.

    When I wrote the javascript to pull the data, I wanted to make my script flexible to easily add or remove fields (such as for the active competition). So my script actually has no idea what object it is looking for- I use two fields per column in the spreadsheet to spell out the object and attribute in question and dump out all of the values are part of a ginormous table, where I can use spreadsheet functions to process it.

    And yes, all of the attributes of the base player object have to be called before any on child objects, because it switches from blank parent object to populated parent object and when it goes blank again, that is the signal that the last field from the pull has been reached.

    So the place that leaves me is there isn't any logic specific to individual objects. I could add some, but I admit I would prefer to find a solution that debugs records as either 1) attributes not in a child object or 2) attributes of child objects to now make it over complicated.

    Maybe I'm kidding myself and I just need to do it. Just wanted to see if someone here had a slick idea on how it could be done in my existing logic framework before I go redesigning (and breaking, maybe followed by fixing) the whole thing.

    Thanks!
    I'd definitely recommend trying to do much of that on the script side.
    What you do can definitely work, but I'd try to limit it to selecting attributes from a known object.

    It would help if you post the parts of the script that cause the errors and what errors they cause. The following is taking some assumptions.

    I assume you access properties using a variable like so:
    call[prop1][prop2]. Maybe assigning it to variables in between. In that case you can still build in some error handling.
    With error handling there's basically two options: the first is ending execution (or if you're in a loop, which i assume you are, using "continue" to go to the next item and basically ignoring the faulty one), or output default data.

    This means all you'd need to do is add a couple rows first trying to see if what you're accessing exists, and if it doesn't, either assign default data to that property/variable and write that to your sheet, or continue the loop and act like nothing happened.

    Alternatively, it's probably a good idea to look into try-catch blocks, which allow you to handle *any* error in a specific way, without stopping code execution.
    Like:

    for (const el of arr) {
    try {
    //your code here
    } catch (error) {
    //Logger.log(error), or some function to write the error to the sheet

    }
    }

    If anywhere in your loop you get an error, it will be able to continue to the next iteration, and it writes out what went wrong.
    You can also wrap your entire code in this, but if you do that it'll stop execution entirely if any error occurs, just like it does now.

    • SirEdge [2609907]
    • Role: Civilian
    • Level: 80
    • Posts: 3220
    • Karma: 2605
    • Last Action: 1 hour
      • 0
    • Reason:
      Are you sure you want to report this post to staff?
      Cancel
    Posted on 20:22:47 - 27/06/22 (1 month ago)
    Post link copied to clipboard Copy post link

    SVD_NL [2363978]

    I'd definitely recommend trying to do much of that on the script side.
    What you do can definitely work, but I'd try to limit it to selecting attributes from a known object.

    It would help if you post the parts of the script that cause the errors and what errors they cause. The following is taking some assumptions.

    I assume you access properties using a variable like so:
    call[prop1][prop2]. Maybe assigning it to variables in between. In that case you can still build in some error handling.
    With error handling there's basically two options: the first is ending execution (or if you're in a loop, which i assume you are, using "continue" to go to the next item and basically ignoring the faulty one), or output default data.

    This means all you'd need to do is add a couple rows first trying to see if what you're accessing exists, and if it doesn't, either assign default data to that property/variable and write that to your sheet, or continue the loop and act like nothing happened.

    Alternatively, it's probably a good idea to look into try-catch blocks, which allow you to handle *any* error in a specific way, without stopping code execution.
    Like:

    for (const el of arr) {
    try {
    //your code here
    } catch (error) {
    //Logger.log(error), or some function to write the error to the sheet

    }
    }

    If anywhere in your loop you get an error, it will be able to continue to the next iteration, and it writes out what went wrong.
    You can also wrap your entire code in this, but if you do that it'll stop execution entirely if any error occurs, just like it does now.
    I am using Try/Catch when I make the API call.  I'll mull on this piece and see if there is a good way to integrate Try/Catch handling for when objects don't exist in the response.

    I did verify- I have 10k records, and this one ID is the only one without a job object (I have hundreds that don't have a job and still have a job object), so I'm fairly certain this is a bug. So I'm kind of hoping they resolve it on their side.

    You have given me a number of things that would probably improve my code's execution. I just have to decide if I'm invested enough for version 3.0. My vision was always to move it into a proper DB when it got this big, but I don't have a good solution for that at present.

    88325a84-98c2-374d-2609907.gif

Reply
Thread Title: