frontends
frontends copied to clipboard
[BUG] useListing missing error handling
Is there an existing issue for this?
- [X] I have searched the existing issues
Current Behavior
Currently calling useListing-composable for example from a component, unhandled error happens.
See code below:
/**
* @public
*/
export function useListing(params?: {
listingType: ListingType;
categoryId?: string;
defaultSearchCriteria?: RequestParameters<"searchPage">;
}): UseListingReturn {
const listingType = params?.listingType || "categoryListing";
// const { getDefaults } = useDefaults({ defaultsKey: contextName }); // ⚠️ necessary?
const { apiClient } = useShopwareContext();
let searchMethod;
if (listingType === "productSearchListing") {
searchMethod = async (searchCriteria: RequestParameters<"searchPage">) => {
return apiClient.invoke("searchPage post /search", {
...searchCriteria,
});
};
} else {
const { category } = useCategory(); // 🚨 This causes unhandled error when category context is not present.
searchMethod = async (searchCriteria: RequestParameters<"searchPage">) => {
if (!category.value?.id) {
throw new Error(
"[useListing][search] Search category id does not exist.",
);
}
return apiClient.invoke(
"readProductListing post /product-listing/{categoryId} sw-include-seo-urls",
{
"sw-include-seo-urls": true,
...searchCriteria,
categoryId: category.value.id,
},
);
};
}
return createListingComposable({
listingKey: listingType,
searchMethod,
searchDefaults:
params?.defaultSearchCriteria || ({} as RequestParameters<"searchPage">), //getDefaults(),
});
}
Expected Behavior
If Category context is not present, the code should use the params.categoryId if exists. If params.categoryId does not exsist, then it should cracefully throw an handled error.
** Fix proposition **
/**
* @public
*/
export function useListing(params?: {
listingType: ListingType;
categoryId?: string;
defaultSearchCriteria?: RequestParameters<"searchPage">;
}): UseListingReturn {
const listingType = params?.listingType || "categoryListing";
const { apiClient } = useShopwareContext();
let searchMethod;
if (listingType === "productSearchListing") {
searchMethod = async (searchCriteria: RequestParameters<"searchPage">) => {
return apiClient.invoke("searchPage post /search", {
...searchCriteria,
});
};
} else {
let resourceId: string | undefined;
try {
const { category } = useCategory();
resourceId = category.value?.id;
}catch(error) {
if (error instanceof ContextError) {
resourceId = params?.categoryId;
} else {
console.error(error);
}
}
searchMethod = async (searchCriteria: RequestParameters<"searchPage">) => {
if (!resourceId) {
throw new Error(
"[useListing][search] Search category id does not exist.",
);
}
return apiClient.invoke(
"readProductListing post /product-listing/{categoryId} sw-include-seo-urls",
{
"sw-include-seo-urls": true,
...searchCriteria,
categoryId: resourceId,
},
);
};
}
return createListingComposable({
listingKey: listingType,
searchMethod,
searchDefaults:
params?.defaultSearchCriteria || ({} as RequestParameters<"searchPage">), //getDefaults(),
});
}
Steps To Reproduce
- Create Nuxt project with Shopware frontends modules and add proper configs
- Create some page
- Create component
listing-example.vue - Add following code to the component
<template>
<!-- No need to add anything here in this example -->
</template>
<script lang="ts" setup>
const {
search,
getElements,
} = useListing({
listingType: "categoryListing",
categoryId: <your-category-id>, // entrypoint to browse
defaultSearchCriteria: { // set the default criteria
search: "", // Add the 'search' property with an empty string value
limit: 25,
p: 1,
},
});
await search({ search: '' });
</script>
### Environment
```markdown
- OS: Latest MacOS Sonoma
- Node: 18.18.0
- Yarn: 1.22.19
Anything else?
No response
Hi @SampoVirmasalo thank you for the reporting issue and proposition of the solution