You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
importcreateFetchClientfrom"openapi-fetch";importtype{paths}from"./schema";constfetchClient=createFetchClient<paths>({baseUrl: "https://httpbin.org",});construn=async()=>{constresult=awaitfetchClient.GET("/status/{code}",{params: {path: {code: 500}},});const{ data, error }=result;// ❌ This will be evaluated as `false`.if(error){console.log("error",error);}else{// ❌// TypeScript has narrowed `data` to a non-nullable type.// But, at runtime, `data` is `undefined`.console.log("data",data);}};run();
In this example, openapi-fetch will return an error of value undefined, because content length is 0 and the response is not okay:
When this happens, the if (error) branch above will be evaluated as false, despite the fact there was actually an error (albeit undefined). (This is also a problem in openapi-react-query.)
TypeScript will then narrow the type of data to a non-nullable type (i.e. exclude undefined). But at runtime, data is actually undefined.
We can mitigate this by avoiding destructuring and using the in operator like so:
construn=async()=>{constresult=awaitfetchClient.GET("/status/{code}",{params: {path: {code: 500}},});// ✅ This will be evaluated as `true`.if("error"inresult){// ✅console.log("error",result.error);}else{console.log("data",result.data);}};
However, it's a shame to lose destructuring. For this reason I wanted to suggest that openapi-fetch could return a discriminant property in FetchResponse, e.g.:
construn=async()=>{constresult=awaitfetchClient.GET("/status/{code}",{params: {path: {code: 500}},});const{ data, error, responseOk }=result;// ✅ This will be evaluated as `true`.if(!responseOk){// ✅console.log("error",error);}else{console.log("data",data);}};
The text was updated successfully, but these errors were encountered:
OliverJAsh
changed the title
openapi-fetch: FetchResponse should return discriminant property
openapi-fetch: add discriminant property to FetchResponseDec 26, 2024
Just wanted to add that this technically isn’t a bug; this is intentional behavior as it relates to empty responses (see that PR, and attached issues, for discussion on the topic).
In general, the following is best practice:
const{ data, error }=result;if(error){// show error}else{// }
Because it’s highly-unusual to not serve any response whatsoever on server error. It is more acceptable to return an empty response for 2xx codes, but even when POSTing or PATCHing it is generally better to return something.
This meshes philosophically with using OpenAPI in the first place—if you aren’t sending responses to the client you’re missing out on a huge benefit of using OpenAPI in the first place (sure, your requests are still typed, but responses are the lions share of what people use OpenAPI for).
I appreciate the suggestion but at this time we won’t consider adding this, because it:
only applies to empty responses
only applies to situations when BOTH your data and error responses are expected to be empty
Designing an API around this edge case isn’t ideal, because you, knowing your schema, could work around this, and/or update your schema and endpoints to return more responses in scenarios where it would make sense to.
Consider the following code:
In this example, openapi-fetch will return an error of value
undefined
, because content length is 0 and the response is not okay:openapi-typescript/packages/openapi-fetch/src/index.js
Lines 205 to 208 in d4689b1
When this happens, the
if (error)
branch above will be evaluated asfalse
, despite the fact there was actually an error (albeitundefined
). (This is also a problem in openapi-react-query.)TypeScript will then narrow the type of
data
to a non-nullable type (i.e. excludeundefined
). But at runtime,data
is actuallyundefined
.We can mitigate this by avoiding destructuring and using the
in
operator like so:However, it's a shame to lose destructuring. For this reason I wanted to suggest that openapi-fetch could return a discriminant property in
FetchResponse
, e.g.:Then, destructuring would be safe again:
The text was updated successfully, but these errors were encountered: