Skip to content
This repository has been archived by the owner on Dec 10, 2021. It is now read-only.

[core] add parseMethod #5

Merged
merged 9 commits into from
Sep 18, 2018
Merged

[core] add parseMethod #5

merged 9 commits into from
Sep 18, 2018

Conversation

williaster
Copy link
Contributor

🏆 Enhancements

  • This adds a parseMethod argument to parseResponse in order to support both json (default) and text responses. This is needed to enable custom response parsing in some cases, for example BigInts which was added to Sqllab recently.
  • Exposes this parseMethod as an optional argument to SupersetClient.get() and .post() calls.

🏠 Internal

  • Bumps @data-ui/build-config to 0.0.14 which has a stricter no-unused-args eslint rule
  • adds .npmrc to .gitignore for local publishing credentials

@kristw @conglei @mistercrunch

@williaster
Copy link
Contributor Author

codecov is stuck in processing, hopefully will post eventually

@@ -75,14 +75,15 @@ class SupersetClient {
);
}

get({ host, url, endpoint, mode, credentials, headers, body, timeout, signal }) {
get({ body, credentials, headers, host, endpoint, mode, parseMethod, signal, timeout, url }) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It starts to get long, do you want to separate into one param per line?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh just notice post is already doing that, then maybe good to spread this one out too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's all based on prettier config, it auto wraps if it's over the 100 char limit (which post is but get is not). we could decrease the char limit if you feel strongly about it tho.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope. this is pretty minor. I'll leave it to you.

};

export default function parseResponse(apiPromise, parseMethod = 'json') {
const responseParser = PARSERS[parseMethod] || PARSERS.json;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can developer pass parseMethod as a custom function in addition to string of predefined parser name?

Copy link
Contributor Author

@williaster williaster Sep 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about that but am not sure a free-form parser makes sense. There are only a few available on the Response object, of which we are exposing text and json.

It doesn't seem worthwhile to copy / mirror the full response API to me (would begin questioning the need for this lib). One option could be to allow null or 'none' as a parseMethod to enable returning the response unmodified and un-read. Beyond that, any custom parsing I think should come from a chained .then(({ json }) => myCustomParser(json))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sgtm

// HTTP 404 or 500 are not rejected, ok is just set to false
if (!response.ok) {
return Promise.reject({
error: response.error || (json && json.error) || text || 'An error occurred',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps should separate error handling for apiResponse, json parsing and text parsing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return apiPromise
  .then((response) => {
    if (!response.ok) {
      return Promise.reject({
        error: response.error,
        status: response.status,
        statusText: response.statusText,
      });
    }
    return response;
  })
  .then(responseParser)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dig the latter^

});
}
.then(json => ({ json, response }))
.catch(() => /* jsonParseError */ response.text().then(text => ({ response, text }))),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean the developer always have to check if output.json exists or not? If output.json does not exist, they should use to output.text instead. If they forget to check. This can cause bugs. I wonder if there is a way to make it more explicit.

Also, generally, does one expect this Promise to reject when fail to parse or resolve text of the supposed-to-be json? IMO, I would expect it to fail and give me the text in the error message for debugging.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah now that we expose the parse method and are explicit about text/json we should probably not clone and fallback to text gracefully, and instead it should probably throw.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this broke a lot of tests, which were falling back to .text() unknowingly because of my mock text response 😜

@williaster
Copy link
Contributor Author

just noting that

  • I updated tests to return a promise, which is an alternative for calling done()
  • I removed unnecessary .catch(throwIfCalled) lines in tests because
    1. tests fail already with unhandled catchs and
    2. they hide errors that you might have in a then block

@williaster
Copy link
Contributor Author

I will also fix the 90.9% of diff hit issue in another PR. there is still 98.5% coverage after this PR, I think the percentage of the lines changed in a PR is not as relevant and the threshold should be on total coverage %.

@williaster williaster merged commit b0790f2 into master Sep 18, 2018
@williaster williaster deleted the chris--parse-method branch September 18, 2018 04:53
@kristw kristw added reviewable Ready for review and removed reviewable Ready for review labels Nov 13, 2018
kristw added a commit that referenced this pull request Apr 17, 2020
* chore: enable live TS in Storybook

* chore: 🤖 manually add tsconfig for storybook

* chore: 🤖 enable typescript for preset-chart-xy
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants