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

chore: fix lint errors on opentelemetry-context-async-hooks #2338

Closed
wants to merge 1 commit into from

Conversation

macabeus
Copy link

@macabeus macabeus commented Jul 8, 2021

Which problem is this PR solving?

Short description of the changes

Fix the following lint errors:

\opentelemetry-js\packages\opentelemetry-context-async-hooks\src\AbstractAsyncHooksContextManager.ts
   71:35  warning  Don't use `Function` as a type  @typescript-eslint/ban-types
  133:60  warning  Don't use `Function` as a type  @typescript-eslint/ban-types
  151:64  warning  Don't use `Function` as a type  @typescript-eslint/ban-types
  175:15  warning  Don't use `Function` as a type  @typescript-eslint/ban-types

\opentelemetry-js\packages\opentelemetry-context-async-hooks\src\AsyncHooksContextManager.ts
  49:22  warning  Forbidden non-null assertion  @typescript-eslint/no-non-null-assertion

@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Jul 8, 2021

CLA Signed

The committers are authorized under a signed CLA.

});
// patch methods that remove a listener
if (typeof ee.removeListener === 'function') {
ee.removeListener = this._patchRemoveListener(ee, ee.removeListener);
const { removeListener, off, removeAllListeners } = ee
Copy link
Author

Choose a reason for hiding this comment

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

@@ -18,6 +18,11 @@ import { ContextManager, Context } from '@opentelemetry/api';
import { EventEmitter } from 'events';

type Func<T> = (...args: unknown[]) => T;
type UnknownFunc = Func<unknown>;
Copy link
Member

Choose a reason for hiding this comment

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

Does this type really save us anything?

Copy link
Author

Choose a reason for hiding this comment

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

It's just to avoid writing Func<unknown> on lines 24 and 76, and I think it's easier to read.
But I could remove this type if you prefer.

@@ -62,13 +67,13 @@ export abstract class AbstractAsyncHooksContextManager
return this._bindEventEmitter(context, target);
}

if (typeof target === 'function') {
if (isUnknownFunc(target)) {
Copy link
Member

Choose a reason for hiding this comment

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

This fixes the lint error technically but doesn't actually fix the problem the lint is trying to point out. This will still return true for constructors so doesn't provide any additional safety. IMO it would be better to use a comment to disable the lint warning as a much more obvious solution.

Copy link
Author

@macabeus macabeus Jul 8, 2021

Choose a reason for hiding this comment

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

There are some workarounds to check if something is a constructor: https://stackoverflow.com/questions/40922531/how-to-check-if-a-javascript-function-is-a-constructor
Perhaps it would better also checking in inUnknownFunc/isGenericFunc if the argument is a constructor and, if yes, returns false?
I would like to avoid a comment ignoring the lint error.

Copy link
Member

@dyladan dyladan Jul 8, 2021

Choose a reason for hiding this comment

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

A comment ignoring the lint error clearly shows "i know this is dangerous and I accept it." A type which obfuscates the danger can come back to bite you later. If a constructor is passed to bind, there really isn't much we can or should do about it but let it fail.

edit: i suppose we could just skip and not bind it... @vmarchaud @obecny what do you think?

Copy link
Member

Choose a reason for hiding this comment

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

As far as I know NodeJs uses internally checks like typeof(arg) === 'function' and they don't care about constructors. Technically it's possible to create a function which can act as constructor and as normal function.

Therefore I don't think we should add a lot complexity here trying to fix a problem which is on caller side.

Copy link
Member

Choose a reason for hiding this comment

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

I agree with @Flarna here, i don't think we had the issue with any instrumentation so adding this much complexity for a problem that we don't have seems pointless right now. I would prefer to wait for an user having this issue to try to fix it

if (ee[methodName] === undefined) return;
ee[methodName] = this._patchAddListener(ee, ee[methodName], context);
const method = ee[methodName];
if (isGenericFunc(method)) {
Copy link
Member

Choose a reason for hiding this comment

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

Same issue here, your type guard doesn't actually differentiate between this function and any other type of function.

Copy link
Author

Choose a reason for hiding this comment

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

Answered above.

@codecov
Copy link

codecov bot commented Jul 8, 2021

Codecov Report

Merging #2338 (f8d9f25) into main (3a327dd) will increase coverage by 0.00%.
The diff coverage is 100.00%.

❗ Current head f8d9f25 differs from pull request most recent head e54869a. Consider uploading reports for the commit e54869a to get more accurate results

@@           Coverage Diff           @@
##             main    #2338   +/-   ##
=======================================
  Coverage   92.77%   92.77%           
=======================================
  Files         145      145           
  Lines        5216     5220    +4     
  Branches     1068     1068           
=======================================
+ Hits         4839     4843    +4     
  Misses        377      377           
Impacted Files Coverage Δ
...sync-hooks/src/AbstractAsyncHooksContextManager.ts 97.18% <100.00%> (+0.16%) ⬆️
...ontext-async-hooks/src/AsyncHooksContextManager.ts 100.00% <100.00%> (ø)

type UnknownFuncReturns<T extends (...args: unknown[]) => unknown> = (...args: unknown[]) => ReturnType<T>;

const isUnknownFunc = (fn: unknown): fn is UnknownFunc => typeof fn === 'function';
const isGenericFunc = <T>(fn: (...args: never[]) => T): fn is Func<T> => typeof fn === 'function';
Copy link
Member

Choose a reason for hiding this comment

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

i don't see why we should differenciate between both, i think the second typeguard is fine to use everywhere no ?

@dyladan
Copy link
Member

dyladan commented Aug 4, 2021

IMO this PR is doing more than just fixing lint errors. Adding function call overhead to such critical functions seems an unnecessary performance penalty to me just to remove lint errors.

@github-actions
Copy link

github-actions bot commented Jan 5, 2022

This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days.

@github-actions github-actions bot added the stale label Jan 5, 2022
@github-actions
Copy link

This PR was closed because it has been stale for 14 days with no activity.

@dyladan dyladan closed this Jan 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants