Skip to content

Error thrown is a String #741

@caub

Description

@caub
  • Version 10.0.0 (latest at time of submission)

Step to repro:

If the token set is expired (we should obviously call const ts = await xero.refreshToken();) the error throw in a String instead of an Error object

import { XeroClient } from 'xero-node';

const xero = new XeroClient({
  clientId: process.env.XERO_CLIENT_ID,
  clientSecret: process.env.XERO_CLIENT_SECRET,
  redirectUris: ['.....'],
  scopes: [
    'openid',
    'profile',
    'email',
    'accounting.transactions',
    'offline_access',
    'accounting.settings',
    'accounting.contacts',
  ],
  state: '...',
});

await xero.initialize();
const tenantId = '22.....5e';
xero.setTokenSet({"id_token":"ey...Q","access_token":"ey...w","expires_at":1740040370,"token_type":"Bearer","refresh_token":"Mk.....","scope":"email profile openid accounting.settings accounting.transactions accounting.contacts offline_access"});

try {
  const { body: { organisations } } = await xero.accountingApi.getOrganisations(tenantId);
  console.log(organisations);
} catch (err) {
  console.log('ERR', typeof err, err);
}

Output:

ERR string {"response":{"statusCode":401,"body":{"Type":null,"Title":"Unauthorized","Status":401,"Detail":"TokenExpired: token expired at 02/20/2025 08:32:50","Instance":"f4a9c0c2-ab46-462c-b70b-9999612e6aa9","Extensions":{}},"headers":{"content-type":"application/json","content-length":"177","server":"nginx","www-authenticate":"Bearer error=invalid_token","xero-correlation-id":"f4a9c0c2-ab46-462c-b70b-9999612e6aa9","expires":"Thu, 20 Feb 2025 12:09:06 GMT","cache-control":"max-age=0, no-cache, no-store","pragma":"no-cache","date":"Thu, 20 Feb 2025 12:09:06 GMT","connection":"close","x-client-tls-ver":"tls1.3","set-cookie":"ak....jQ==; Domain=.xero.com; Path=/; Expires=Thu, 20 Feb 2025 14:09:06 GMT; Max-Age=7200; SameSite=None; Secure"},"request":{"url":{"protocol":"https:","port":443,"host":"api.xero.com","path":"/api.xro/2.0/Organisation"},"headers":{"accept":"application/json","content-type":"application/json","user-agent":"xero-node-10.0.0","xero-tenant-id":"22......5e","authorization":"Bearer ey...Jw","content-length":"2","accept-encoding":"gzip, compress, deflate, br","host":"api.xero.com"},"method":"GET"}},"body":{"Type":null,"Title":"Unauthorized","Status":401,"Detail":"TokenExpired: token expired at 02/20/2025 08:32:50","Instance":"f4a9c0c2-ab46-462c-b70b-9999612e6aa9","Extensions":{}}

There are other cases where the error is a String

It should not throw an error as a string because it's not practical, it should be an Error object with ideally a status code (401, 403, ..), a message, and more data if needed

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions