rxjs-tslint-rules icon indicating copy to clipboard operation
rxjs-tslint-rules copied to clipboard

rxjs-throw-error option to specifiy error names

Open moeriki opened this issue 7 years ago • 7 comments

I have in an Angular project warnings for rxjs-throw-error on code like this.

throwError(new HttpErrorResponse({}))

I have worked with subclassing Error on other projects before as well.

Would you consider a PR adding an option to set error names.

eg.

"rxjs-throw-error": {
  "options": { "errorNames": ["Error", "HttpErrorResponse"] },
  "severity": "warn",
}

moeriki avatar Dec 07 '18 12:12 moeriki

Subclassing Error should be fine, as the rule uses the type information to determine whether the argument could be an Error. I guess HttpErrorResponse does not subclass Error if a warning is effected.

I'll give some thought to adding an option to make it a little more flexible.

cartant avatar Dec 07 '18 13:12 cartant

Good to know.

For what it's worth, me throwing HttpErrorResponse is only in tests since Angular throws them otherwise. So I can easily disable them.

moeriki avatar Dec 07 '18 13:12 moeriki

I've also come across this. The signature of the class is: class HttpErrorResponse extends HttpResponseBase implements Error, which I would assume to work.

NickLydon avatar Mar 19 '20 08:03 NickLydon

implements is a TypeScript feature, though. Technically, it's still not an Error. To be an Error it would have to extend Error. Inheritance is the worst.

cartant avatar Mar 19 '20 08:03 cartant

I've never implemented a ts-lint rule or used the typescript compiler api, so forgive me if this is dumb. Error is defined as an interface:

interface Error {
    name: string;
    message: string;
    stack?: string;
}

Could you use this approach to check if the object implements this?

NickLydon avatar Mar 19 '20 09:03 NickLydon

@NickLydon

Could you use this approach to check if the object implements this?

Not easily. The check is done here and that function has only the type - it does not have the declarations:

  const baseTypes = type.getBaseTypes();
  if (!baseTypes) {
    return false;
  }
  return baseTypes.some(t => couldBeType(t, name, qualified));

I imagine that implemented interfaces are not included in what's returned from getBaseTypes. Whether they are available via some other method, IDK. Figuring out how to use these parts of the TypeScript API is a PITA. I will have a look later. Thanks for the suggestion, though.

cartant avatar Mar 19 '20 20:03 cartant

@NickLydon It's possible that this issue will be resolved with the changes in 4.29.2 - as that release includes an update to tsutils-etc that looks at implements clauses.

cartant avatar Mar 19 '20 22:03 cartant