Skip to content

Commit

Permalink
Fix media store error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
obulat committed Jul 14, 2023
1 parent f9520f7 commit 1f79c95
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 117 deletions.
12 changes: 6 additions & 6 deletions frontend/src/components/VSearchGrid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ import {
} from "~/constants/media"
import { NO_RESULT } from "~/constants/errors"
import { defineEvent } from "~/types/emits"
import type { FetchState } from "~/types/fetch-state"
import type { ApiQueryParams } from "~/utils/search-query-transform"
import { getAdditionalSources } from "~/utils/get-additional-sources"
import { useMediaStore } from "~/stores/media"
import { useFeatureFlagStore } from "~/stores/feature-flag"
import VExternalSearchForm from "~/components/VExternalSearch/VExternalSearchForm.vue"
Expand Down Expand Up @@ -79,10 +79,6 @@ export default defineComponent({
type: String as PropType<SearchType>,
required: true,
},
fetchState: {
type: Object as PropType<FetchState>,
required: true,
},
resultsCount: {
type: Number,
required: true,
Expand All @@ -92,13 +88,16 @@ export default defineComponent({
tab: defineEvent<[KeyboardEvent]>(),
},
setup(props) {
const mediaStore = useMediaStore()
const fetchState = computed(() => mediaStore.fetchState)
const hasNoResults = computed(() => {
// noResult is hard-coded for search types that are not currently
// supported by Openverse built-in search
return props.supported
? Boolean(
props.query.q !== "" &&
props.fetchState.hasStarted &&
fetchState.value.hasStarted &&
props.resultsCount === 0
)
: false
Expand Down Expand Up @@ -136,6 +135,7 @@ export default defineComponent({
NO_RESULT,
externalSources,
searchTerm,
fetchState,
}
},
})
Expand Down
35 changes: 26 additions & 9 deletions frontend/src/middleware/search.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import { useSearchStore } from "~/stores/search"

import { useMediaStore } from "~/stores/media"

import type { Middleware } from "@nuxt/types"

export const searchMiddleware: Middleware = ({ redirect, route, $pinia }) => {
export const searchMiddleware: Middleware = async ({
redirect,
route,
$pinia,
error: nuxtError,
}) => {
const {
query: { q },
query: { q: rawQ },
} = route
const q = Array.isArray(rawQ) ? rawQ[0] : rawQ

/**
* This middleware redirects any search without a query to the homepage.
* This is meant to block direct access to /search and all sub-routes.
Expand All @@ -19,13 +28,21 @@ export const searchMiddleware: Middleware = ({ redirect, route, $pinia }) => {
* Note that the search by creator is not displayed in the UI.
*/
if (!q) return redirect("/")
/**
* We need to make sure that query `q` exists before checking if it matches
* the store searchTerm.
*/

const searchStore = useSearchStore($pinia)
const querySearchTerm = Array.isArray(q) ? q[0] : q
if (querySearchTerm !== searchStore.searchTerm) {
searchStore.setSearchTerm(querySearchTerm)

searchStore.setSearchStateFromUrl({
path: route.path,
urlQuery: route.query,
})

// Fetch results before rendering the page on the server.
if (process.server) {
const mediaStore = useMediaStore($pinia)
const results = await mediaStore.fetchMedia()

if (!results) {
nuxtError(mediaStore.fetchState.fetchingError ?? { statusCode: 404 })
}
}
}
29 changes: 15 additions & 14 deletions frontend/src/pages/search.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@
import { isShallowEqualObjects } from "@wordpress/is-shallow-equal"
import { computed, inject, watch } from "vue"
import { storeToRefs } from "pinia"
import { defineComponent, useMeta, useRoute } from "@nuxtjs/composition-api"
import {
defineComponent,
useContext,
useMeta,
useRoute,
} from "@nuxtjs/composition-api"
import { searchMiddleware } from "~/middleware/search"
import { useMediaStore } from "~/stores/media"
Expand All @@ -54,6 +59,7 @@ export default defineComponent({
},
layout: "search-layout",
middleware: searchMiddleware,
fetchOnServer: false,
setup() {
const showScrollButton = inject(ShowScrollButtonKey)
const isSidebarVisible = inject(IsSidebarVisibleKey)
Expand Down Expand Up @@ -89,10 +95,17 @@ export default defineComponent({
meta: [{ hid: "robots", name: "robots", content: "all" }],
})
const { error: nuxtError } = useContext()
const fetchMedia = async (
payload: { shouldPersistMedia?: boolean } = {}
) => {
return mediaStore.fetchMedia(payload)
const results = await mediaStore.fetchMedia(payload)
if (!results) {
const errorStatus = mediaStore.fetchState.fetchingError?.statusCode
if (errorStatus !== 404)
return nuxtError(mediaStore.fetchState.fetchingError)
}
}
watch(route, async (newRoute, oldRoute) => {
Expand Down Expand Up @@ -130,18 +143,6 @@ export default defineComponent({
fetchMedia,
}
},
/**
* asyncData blocks the rendering of the page, so we only
* update the state from the route here, and do not fetch media.
*/
async asyncData({ route, $pinia }) {
const searchStore = useSearchStore($pinia)
await searchStore.initProviderFilters()
searchStore.setSearchStateFromUrl({
path: route.path,
urlQuery: route.query,
})
},
/**
* Fetch media, if necessary, in a non-blocking way.
*/
Expand Down
Loading

0 comments on commit 1f79c95

Please sign in to comment.