Skip to content

Conversation

@michaelcozzolino
Copy link
Contributor

@michaelcozzolino michaelcozzolino commented Mar 7, 2025

Before submitting the PR, please make sure you do the following

  • Read the Contributing Guidelines.
  • Read the Pull Request Guidelines.
  • Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
  • Provide a description in this PR that addresses what the PR is solving, or reference the issue that it solves (e.g. fixes #123).
  • Ideally, include relevant tests that fail without this PR but pass with it.
⚠️ Slowing down new functions

Warning: Slowing down new functions

As the VueUse audience continues to grow, we have been inundated with an overwhelming number of feature requests and pull requests. As a result, maintaining the project has become increasingly challenging and has stretched our capacity to its limits. As such, in the near future, we may need to slow down our acceptance of new features and prioritize the stability and quality of existing functions. Please note that new features for VueUse may not be accepted at this time. If you have any new ideas, we suggest that you first incorporate them into your own codebase, iterate on them to suit your needs, and assess their generalizability. If you strongly believe that your ideas are beneficial to the community, you may submit a pull request along with your use cases, and we would be happy to review and discuss them. Thank you for your understanding.


Description

This PR introduces a generic type system for the AxiosError, in detail:

  • When an Error is thrown by axios we cannot ensure that it is an AxiosError, so I added an axiosError ref that will be populated only when the Error is an instance of AxiosError, furthermore when the error is not AxiosError, the error ref will still be populated, and I also added a callback (onAxiosError) that will be executed only when we have an AxiosError, if that is the case, also the onError callback will be executed.
  • Now that we have the AxiosError, basically, according to me, the developer is mainly looking for the data property of the error response, and, also for consistency with the data property of a successful AxiosResponse, I added a computed property axiosErrorResponseData that returns exactly the data of the error response.

Example usage

// Some utility types
type DefaultStrictUseAxiosReturn<Response, Payload = unknown, AxiosErrorResponse = unknown> = StrictUseAxiosReturn<
    Response,
    AxiosResponse<Response>,
    Payload,
    AxiosErrorResponse,
    UseAxiosOptionsWithInitialData<Response>
>

export type PromiseLikeStrictUseAxiosReturn<Response, Payload = unknown, AxiosErrorResponse = unknown> =
    Promise<DefaultStrictUseAxiosReturn<Response, Payload, AxiosErrorResponse>>
    & DefaultStrictUseAxiosReturn<Response, Payload, AxiosErrorResponse>

interface MyResponse {
    id: number,
    name: string
}

interface MyPayload {
    name: string
}

interface ErrorResponse {
    errors: { name: string[] }
}

function updateApiData(options: UseAxiosOptionsWithInitialData<MyResponse, ErrorResponse>): PromiseLikeStrictUseAxiosReturn<MyResponse, MyPayload, ErrorResponse> {
    return useAxios(
        '/something',
        { method: 'put' },
        options,
    )
}

const { execute, axiosError, axiosErrorResponseData, data } = updateApiData({
    initialData: { id: 1, name: 'Michael' },
  onAxiosError: (e) => {
    console.log(e?.response?.data.errors.name)
  },
})

Additional context

If the feature is accepted, I will add tests and update the docs. There is no breaking change in the composable, but only in the types, as it seems unavoidable.
Let me know if the naming is fine, I think they are pretty descriptive, but I'm looking forward to suggestions, if any.

@dosubot dosubot bot added size:M This PR changes 30-99 lines, ignoring generated files. enhancement New feature or request labels Mar 7, 2025
@michaelcozzolino
Copy link
Contributor Author

@antfu @OrbisK any feedback?

isCanceled: Ref<boolean>
}
export interface StrictUseAxiosReturn<T, R, D, O extends UseAxiosOptions = UseAxiosOptions<T>> extends UseAxiosReturn<T, R, D, O> {
export interface StrictUseAxiosReturn<T, R, D, AxiosErrorResponseData = unknown, O extends UseAxiosOptions<T, AxiosErrorResponseData> = UseAxiosOptions<T, AxiosErrorResponseData>> extends UseAxiosReturn<T, R, D, AxiosErrorResponseData, O> {
Copy link
Member

Choose a reason for hiding this comment

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

this type is breaking

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 unavoidable, do you have any suggestions to make it non breaking?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@OrbisK hello, some time has passed, what is the status of the review? would it be possible to merge it as a breaking change after adding tests? I'm relying a lot on useAxios and this feature is really needed and i also think that many other people need it

@michaelcozzolino michaelcozzolino requested a review from OrbisK March 26, 2025 13:21
@OrbisK OrbisK requested review from 43081j, ferferga and ilyaliao May 16, 2025 19:48
@43081j
Copy link
Collaborator

43081j commented May 17, 2025

we should be able to simplify this a whole bunch.

i don't think you need to introduce a new type parameter at all.

an axios error is basically typed to the request and response (lets call them Request and Response). that means you can call isAxiosError<Response, Request> using our existing type parameters (T and D - isAxiosError<T, D>).

although im not entirely sure about this change anyway. we already expose the error, we're just doing this so we can filter down to axios errors i suppose?

@michaelcozzolino
Copy link
Contributor Author

michaelcozzolino commented May 17, 2025

we should be able to simplify this a whole bunch.

i don't think you need to introduce a new type parameter at all.

an axios error is basically typed to the request and response (lets call them Request and Response). that means you can call isAxiosError<Response, Request> using our existing type parameters (T and D - isAxiosError<T, D>).

yes, but I have to make the check on every request in my codebase.

although im not entirely sure about this change anyway. we already expose the error, we're just doing this so we can filter down to axios errors i suppose?

yes and to be sure that whenever an error is thrown it is related to the response and not to the fact that axios caught an error that is coming from somewhere else E.G the developer uses an interceptor and and a non axios error is thrown there.

@43081j
Copy link
Collaborator

43081j commented May 17, 2025

I think you misunderstood a little. I was telling you two things:

  1. In this change, you don't need a new type parameter (for the reasons I mentioned). You can still introduce the new option and return property without a new type parameter
  2. If the change is sensible or not

@michaelcozzolino
Copy link
Contributor Author

michaelcozzolino commented May 17, 2025

I think you misunderstood a little. I was telling you two things:

  1. In this change, you don't need a new type parameter (for the reasons I mentioned). You can still introduce the new option and return property without a new type parameter
  2. If the change is sensible or not

ok I think I understood, I will update the PR soon

@michaelcozzolino
Copy link
Contributor Author

michaelcozzolino commented May 18, 2025

I think you misunderstood a little. I was telling you two things:

  1. In this change, you don't need a new type parameter (for the reasons I mentioned). You can still introduce the new option and return property without a new type parameter
  2. If the change is sensible or not

Updated with your suggestions if I understood correctly. so basically now the final data received from a request could be something like
MyResponse | MyErrorResponse
because we have to assign that error to the same data variable. furthermore I am not sure if we have to assign the error data only on axios error or any errors, probably the second case is more suitable. If this is the case, also this is a breaking change, indeed a test now fails. Let me know if the approach I applied is right

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants