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

Wrong type leading to a tricky ECONNRESET bug #1419

Open
nem035 opened this issue Jan 5, 2024 · 3 comments
Open

Wrong type leading to a tricky ECONNRESET bug #1419

nem035 opened this issue Jan 5, 2024 · 3 comments
Labels

Comments

@nem035
Copy link

nem035 commented Jan 5, 2024

Bugs

  1. TypeScript Bug: The type of limit is invalid for the IRequestRunQuery.
  2. API Bug: Looker API returns ECONNRESET for invalid value for limit

Explanation

The limit property is defined as a string for the WriteQuery type (used for creating a query or running it inline) but defined as a number for the IRequestRunQuery type (used for running a previously created query).

Not only is this confusing...but it's also wrong.

Passing a number for the run query API calls errors with ECONNRESET every time.

const params: Partial<IWriteQuery> = {
  model: ...,
  view: ...,
  fields: [...],
};
const query = await sdk.ok(sdk.create_query(params));
const runParams: IRequestRunQuery = {
  query_id: 1,
  limit: 1 // <--- this can't be a number but types say it should be!
}
const result = await sdk.ok(sdk.run_query(runParams)) // <-- ECONNRESET every time.

Changing the 1 to a "1" does not lead to an ECONNRESET anymore but does conflict with the existing types and thus must be @ts-ignore-ed.

const params: Partial<IWriteQuery> = {
  model: ...,
  view: ...,
  fields: [...],
};
const query = await sdk.ok(sdk.create_query(params));
const runParams: IRequestRunQuery = {
  query_id: 1,
  // @ts-ignore
  limit: "1" // <--- this can't be a number but types say it should be!
}
const result = await sdk.ok(sdk.run_query(runParams)) // <-- ECONNRESET every time.

Note: the run query call also errors with ECONNRESET for any invalid value for limit, such as an empty string "":

const params: Partial<IWriteQuery> = {
  model: ...,
  view: ...,
  fields: [...],
};
const query = await sdk.ok(sdk.create_query(params));
const runParams: IRequestRunQuery = {
  query_id: 1,
  limit: "" // <--- this is invalid
}
const result = await sdk.ok(sdk.run_query(runParams)) // <-- ECONNRESET every time.
@github-actions github-actions bot added need triage p3 Priority 3 labels Jan 5, 2024
@nem035
Copy link
Author

nem035 commented Jan 5, 2024

Ok it seems the ECONRESET error isn't that simple. I'm able to reproduce it on simple queries by adding filters or sorts as well...

It's difficult to pinpoint why exactly it happens but it does seem to be affected by mishandling of bad requests (should throw 4XX error instead)

@nem035 nem035 changed the title Wrong type leading to a tricky ECONRESET bug Wrong type leading to a tricky ECONNRESET bug Jan 5, 2024
@nem035
Copy link
Author

nem035 commented Jan 10, 2024

I managed to isolate the issue to a single endpoint and am able to consistently reproduce it.

The erroring URL is a GET request to /queries/:query_id/run/json_bi?limit=1, like this:

GET https://$OBFUSCATED.looker.com:19999/api/4.0/queries/751560/run/json_bi?limit=1

After digging into the Looker SDK code base, the error returned is:

{
  "name": "RequestError",
  "message": "Error: socket hang up",
  "cause": {
    "code": "ECONNRESET"
  },
  "error": {
    "code": "ECONNRESET"
  },
  "options": {
    "encoding": null,
    "headers": {
      "x-looker-appid": "...",
      "Authorization": "Bearer $OBFUSCATED$"
    },
    "json": null,
    "method": "GET",
    "rejectUnauthorized": true,
    "resolveWithFullResponse": true,
    "timeout": 120000,
    "url": "https://$OBFUSCATED.looker.com:19999/api/4.0/queries/751560/run/json_bi?limit=1"
    "simple": true,
    "transform2xxOnly": false
  }
}

And the erroring is caught here: 

let statusMessage = `${method} ${path}`;

@nem035
Copy link
Author

nem035 commented Jan 10, 2024

On further inspection, it seems that the json_bi format is the issue.

Using the json format doesn't lead to ECONNRESET while using json_bi does.

This is quite strange but I am able to reproduce the results (tried 5 times).

Confusingly, json_bi is the recommended format even though it leads to an obfuscated issue like this.

image

This works:

GET /api/4.0/queries/:query_id/run/json

This throws ECONNRESET each time (for some queries):

GET /api/4.0/queries/:query_id/run/json_bi

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

No branches or pull requests

1 participant