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

feat: ts-rest client throw on error status code #522

Closed
wants to merge 4 commits into from

Conversation

toteto
Copy link
Contributor

@toteto toteto commented Mar 22, 2024

Resolves #520

There are no breaking changes with this new addition. In order to get this behavior of the client to throw on error status code, a parameter of throwOnErrorStatus: true needs to be provided to the initClient options.

Open for changes or feedback to the code. If you don't see this as an addition of the @ts-rest/core client, looking for suggestion how such behavior can be achieved by separate client that can be in separate package/repository.

Copy link

vercel bot commented Mar 22, 2024

@toteto is attempting to deploy a commit to the ts-rest Team on Vercel.

A member of the Team first needs to authorize it.

Copy link

changeset-bot bot commented Mar 22, 2024

⚠️ No Changeset found

Latest commit: 5884d86

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link

sonarcloud bot commented Mar 25, 2024

Quality Gate Passed Quality Gate passed

Issues
12 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
9.6% Duplication on New Code

See analysis details on SonarCloud

Copy link

nx-cloud bot commented Mar 25, 2024

☁️ Nx Cloud Report

CI is running/has finished running commands for commit 5884d86. As they complete they will appear below. Click to see the status, the terminal output, and the build insights.

📂 See all runs for this CI Pipeline Execution


✅ Successfully ran 4 targets

Sent with 💌 from NxCloud.


export type FetchOptions = Omit<RequestInit, 'method' | 'headers' | 'body'>;

export interface OverrideableClientArgs {
baseUrl: string;
credentials?: RequestCredentials;
jsonQuery?: boolean;
throwOnErrorStatus?: boolean;
Copy link
Member

Choose a reason for hiding this comment

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

This option can be confusing because it will be available to the rest of the tanstack clients, however we don't/cannot really throw there. However, it actually needs to be available for all clients, because we still expose the vanilla .query() and .mutation() functions to these clients.

args?: Prettify<TArgs>,
) => Promise<
Prettify<
TClientArgs['throwOnErrorStatus'] extends true
Copy link
Member

Choose a reason for hiding this comment

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

This will be incorrectly typed if the throwOnErrorStatus was overriden. Need to check if it was overriden from TArgs.

Comment on lines +390 to +391
(clientArgs.throwOnErrorStatus && response.status < 200) ||
response.status >= 300
Copy link
Member

Choose a reason for hiding this comment

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

Misplaced parentheses

TAppRoute,
TErrorStatus extends undefined ? ErrorHttpStatusCode : TErrorStatus
> {
if (error == null) return false;
Copy link
Member

Choose a reason for hiding this comment

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

We don't use non-strict equality in our code base. In addition, you don't need to check for falsy values before using instanceof

TErrorStatus extends undefined ? ErrorHttpStatusCode : TErrorStatus
> {
if (error == null) return false;
if (!(error instanceof ErrorStatusResponseError)) return false;
Copy link
Member

Choose a reason for hiding this comment

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

We don't use shorthand single-line ifs in our codebase.


if (errorStatusResponseError.route.path !== route.path) return false;

if (status == null) return true;
Copy link
Member

@Gabrola Gabrola Apr 2, 2024

Choose a reason for hiding this comment

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

Optional args are undefined, not null. This only works because of the non-strict equality. Should be

Suggested change
if (status == null) return true;
if (status === undefined) return true;

But just easier to do if (!status) { return true; } and easier to read

constructor(
public readonly route: TAppRoute,
public readonly response: ErrorResponse<TAppRoute, TErrorStatus>,
public readonly request: unknown,
Copy link
Member

Choose a reason for hiding this comment

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

Can't this be ClientInferRequest<TAppRoute, ClientArgs>?

ErrorHttpStatusCode
>;

if (errorStatusResponseError.route.path !== route.path) return false;
Copy link
Member

Choose a reason for hiding this comment

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

Need to check the method too, not only the path.

[401, 403, 500],
);

if (!isHealthError) fail('should be health error');
Copy link
Member

Choose a reason for hiding this comment

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

Use expect(isHealthError).toBe(true)

status?: TErrorStatus | TErrorStatus[],
): error is ErrorStatusResponseError<
TAppRoute,
TErrorStatus extends undefined ? ErrorHttpStatusCode : TErrorStatus
Copy link
Member

Choose a reason for hiding this comment

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

TErrorStatus extends undefined will never be true because you already declared it as TErrorStatus extends ErrorHttpStatusCode. Even if not, T extends undefined in general doesn't work that way for optional parameters, because they resolve as unknown not undefined, and actually because extends is distributive you need to do unknown extends T not T extends unknown

This should work fine if you just replace TErrorStatus extends undefined ? ErrorHttpStatusCode : TErrorStatus with TErrorStatus because you already gave it a default value of ErrorHttpStatusCode, so it will take that if you don't pass status

@toteto
Copy link
Contributor Author

toteto commented May 23, 2024

Closing in favour of having un-opinionated implementation

@toteto toteto closed this May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature Request: Create new ts-rest client that throws exceptions for error responses
2 participants