Conversation
|
@gelbal @pranasziaukas I added the logic to handle both relative and absolute Urls and corresponding tests that seem to be working. But as always, please give it a look since you might come up with a better way to handle this or notice something I missed. Thanks! |
|
@laziob I see balenaCI returns failed because of not-prettified code. Can you please run
I wonder if it makes sense to include |
gelbal
left a comment
There was a problem hiding this comment.
Good stuff pushing this forward Ezequiel. I typed couple of suggestions and discussion points.
| } | ||
|
|
||
| // If its not a relative URL string, we make sure if its a string or an URL. It its a string, we convert it to an URL object. | ||
| if (typeof destinationUrl === 'string') { |
There was a problem hiding this comment.
You can combine this if statement with the one above to eliminate the double check for string. The code and comments will also read better.
if (typeof destinationUrl === 'string') {
if (destinationUrl.match(relativeRegex)) {
return '';
} else {
....
}There was a problem hiding this comment.
@gelbal Lol I was going to do it that way first, but for some reason I remembered that once I saw the if statements one below the other and that that was the usual practice or something like that and went the other way. Sure I'll change that.
There was a problem hiding this comment.
@laziob oh I see you made a major rework. Actually I liked your previous implementation as it was cleaner (once you combine the new if statements). So the code handles the string scenario first and the proceeds to handling the URL scenario. Can you please bring it back? : )
There was a problem hiding this comment.
Petros (ex-CTO) made a pretty good presentation about such design principle actually (he calls it normalizing if). I highly recommend listening to it:
https://docs.google.com/presentation/d/1hFV5YBL4FflfN7OIJr6eZrUV4Pk158wOXWzea1ANTnM/edit#slide=id.p
https://drive.google.com/file/d/1xtHev7HUwbASdasf8cWfG9O2oHdlXX43/view
There was a problem hiding this comment.
@gelbal It still handles the string scenario first. The code above is for the other parameter that stays that way regardless of the destinationUrl. The reason I changed it was because with the previous design, I had to repeat much more code, once for each if and even then couldnt make it work properly. In fact I dont even like this design, since it still repeats code. But it repeated less than the previous one. I still also dont believe we should be handling relative URLs through this method. It kind of undermines the use of TypeScript and gives place to the bad use of the method in resin-site, since I still think they shoudnt be forcing this method in every link "just in case". Performance wise it doesnt make sense to me. resin-site should have a better way to identify outbound links from inbound links, and call this method only on outbound links.
Having said that, I could try go back to the previous design, but I could make it work with the previous design. This was so far the only way I achieved what I wanted lol.
There was a problem hiding this comment.
To put an example, Hub handles it like this:
deployUrl = getExternalLinkWithTracking( 'https://dashboard.balena-cloud.com/deploy?repoUrl=${repoUrl}')
So it explicitly uses the method on the only domain where its needed. For example marketing site only needs to use it on the Login and Signup buttons, which exist only in 2 places, the header (for most of the resin-site pages) , like here and the box for on the landing page.
So its not that they need to detect relative urls in a simple way. Its that they have to detect URLs to another balena domain, not even including subdomains.
If using a list is the best way to do it I dont really know, but if its needed to be raised for further discussion Im up for that. Whats the proper way and place to raise it? ALthough It just seems too much for the task at hand tbh.
There was a problem hiding this comment.
@gelbal we need to work on this soon since its the only thing preventing marketing sites to update to the last analytics client. Its still using 0.12 so its not stiching sessions nor using the last referrer updates.
There was a problem hiding this comment.
@iamsolankiamit @thgreasi @JSReds if you could take a look into the discussion too so we can decide on how we advance it would be really helpful and appreciated! thanks!
There was a problem hiding this comment.
Hey @laziob cc @thgreasi @JSReds @iamsolankiamit, how about introducing an optional parameter (in the analytics-client constructor) for a list of domains to track?
We could retrieve this list either directly from the client that calls analytics-client or indirectly from the projectName configuration stored in the analytics-backend. At first it'll have the following content:
*.balena.io
*.balena-cloud.com
We will probably end up updating this list seldom so it's not a big maintenance issue to store it on the analytics-backend side.
Edit: Thinking it further, part of my suggestion actually means that analytics-client needs to retrieve such stateful information from the analytics-backend at each initialization. So maybe that's a no-go. It's cleaner for the component to configure analytics-client directly (without dependency on the backend).
There was a problem hiding this comment.
Having said these, let's still go ahead with working on this PR to add support for relative URL detection.
src/url-params.ts
Outdated
|
|
||
| // If its not a relative URL string, we make sure if its a string or an URL. It its a string, we convert it to an URL object. | ||
| if (typeof destinationUrl === 'string') { | ||
| destinationUrl = new URL(destinationUrl); |
There was a problem hiding this comment.
We need to handle the errors here when the incoming string cannot be translated to a URL. I'm not sure if relativeRegex ensures that the string with no match is actually a URL.
There was a problem hiding this comment.
@gelbal Ohh yeap you are right. let me look into this.
src/url-params.ts
Outdated
| ? destinationDomainMatch.toString() | ||
| : null; | ||
| } catch (err) { | ||
| return ''; //I dont know what we should do when an error like this happens. Any ideas?? |
There was a problem hiding this comment.
Good question. We could do console.log(err) but I don't know how much that'd help. I think it's fine to at least catch it as you do here.
There was a problem hiding this comment.
@thgreasi @iamsolankiamit any suggestions on handling such caught errors in modules?
It's OK to silently fail here but I wonder what's the best practice.
| // the logic and take that longer TLD as the main domain, for example hub.balena.edge.io -> edge.io | ||
| const regex = /([a-zA-Z0-9-]+)(\.[a-zA-Z]{2,3})?(\.[a-zA-Z]+$)/g; | ||
|
|
||
| let actualDomainMatch; |
There was a problem hiding this comment.
I actually prefer it here, next to where it's first assigned, so that's easier to follow.
Also type it as:
let actualDomainMatch: RegExpMatchArray | null;
src/url-params.ts
Outdated
| let destinationDomainMatch; | ||
| let destinationDomain; | ||
| let actualDomainMatch; | ||
| let actualDomain; |
There was a problem hiding this comment.
All these are typed as any, which isn't good...
After the changes suggested bellow this will be:
| let destinationDomainMatch; | |
| let destinationDomain; | |
| let actualDomainMatch; | |
| let actualDomain; | |
| let destinationDomain: string | undefined; |
but I would suggest to push it lower, near the place it's first assinged.
src/url-params.ts
Outdated
| const destinationDomainMatch = destinationUrl | ||
| ? destinationUrl.hostname.match(regex) | ||
| : null; | ||
| actualDomain = actualDomainMatch ? actualDomainMatch.toString() : null; |
There was a problem hiding this comment.
| actualDomain = actualDomainMatch ? actualDomainMatch.toString() : null; | |
| const actualDomain = actualDomainMatch ? actualDomainMatch.toString() : null; |
and if you have recent enough TS in this project, then you can do:
const actualDomain = actualDomainMatch?.[0]; // this is inferred as `string | null` automatically
prefer explicitly reading the first match, that relying on toString().
src/url-params.ts
Outdated
| if (typeof destinationUrl === 'string') { | ||
| try { | ||
| destinationUrl = new URL(destinationUrl); | ||
| destinationDomainMatch = destinationUrl |
There was a problem hiding this comment.
| destinationDomainMatch = destinationUrl | |
| const destinationDomainMatch = destinationUrl |
Just declare it in this scope, since this is only used in this limited scope as a temp variable and its value isn't useful outside this context.
src/url-params.ts
Outdated
| return ''; //I dont know what we should do when an error like this happens. Any ideas?? | ||
| } | ||
| } else { | ||
| destinationDomainMatch = destinationUrl |
There was a problem hiding this comment.
| destinationDomainMatch = destinationUrl | |
| const destinationDomainMatch = destinationUrl |
Just declare it in this scope, since this is only used in this limited scope as a temp variable and its value isn't useful outside this context.
src/url-params.ts
Outdated
| destinationDomain = destinationDomainMatch | ||
| ? destinationDomainMatch.toString() | ||
| : null; |
There was a problem hiding this comment.
| destinationDomain = destinationDomainMatch | |
| ? destinationDomainMatch.toString() | |
| : null; | |
| destinationDomain = destinationDomainMatch?.[0]; |
src/url-params.ts
Outdated
| destinationDomain = destinationDomainMatch | ||
| ? destinationDomainMatch.toString() | ||
| : null; |
There was a problem hiding this comment.
| destinationDomain = destinationDomainMatch | |
| ? destinationDomainMatch.toString() | |
| : null; | |
| destinationDomain = destinationDomainMatch?.[0]; |
dd34960 to
c6811c1
Compare
|
@gelbal I think I properly reverted to the previous way we handled the relative URLs, hadnling string first and so but keeping some error handling. The unit tests are still working properly too. So please take a look when possible. On the other hand, I still dont know whats the best way to pass href and window.location.hostname as arguments to getQueryString() on the resin-site side here which is adressed on the PR though but with no solution yet |
gelbal
left a comment
There was a problem hiding this comment.
Good stuff @laziob. I like this version the best.
The error you get is:
Error: File src/url-params.ts hasn't been formatted with prettier
Can you please call npm run prettify and squash all your commits before pushing once more?
src/url-params.ts
Outdated
| return ''; | ||
| } | ||
|
|
||
| // If its not a relative URL string, we make sure if its a string or an URL. It its a string, we convert it to an URL object. |
There was a problem hiding this comment.
I don't think we need a comment here as the code is self explanatory.
src/url-params.ts
Outdated
| ? destinationDomainMatch.toString() | ||
| : null; | ||
| } catch (err) { | ||
| return ''; //I dont know what we should do when an error like this happens. Any ideas?? |
There was a problem hiding this comment.
@thgreasi @iamsolankiamit any suggestions on handling such caught errors in modules?
It's OK to silently fail here but I wonder what's the best practice.
Change-type: Minor Signed-off-by: Ezequiel Boehler ezequiel@balena.io
c6811c1 to
43e9be3
Compare
|
Hey @laziob, clicking on the It's best to get rid of that comment anyhow. Can you please add Exposing the error seems more useful than harmful. On other news, is this PR waiting for some other changes? |
…a-io-modules/analytics-client into getQueryString_expect_relative_url
|
@balena-ci I self certify! |
Change-type: Minor
Signed-off-by: Ezequiel Boehler ezequiel@balena.io