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

Enhance DOI Search Error Handling #450

Merged
merged 8 commits into from
Feb 4, 2025
2 changes: 1 addition & 1 deletion cypress/e2e/searchOrganization.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ describe('Search Organizations', () => {
// timeout for the query results to return
// return introduction text
.get('.alert-warning', { timeout: 60000 })
.should('contain', 'No organizations found.')
.should('contain', 'No results found.')
})
})

Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/searchPerson.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ describe('Search People', () => {
.type('xxxxxyyyyy{enter}')
// timeout for the query results to return
.get('.alert-warning', { timeout: 60000 })
.should('contain', 'No people found.')
.should('contain', 'No results found.')
})
})

Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/searchWork.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ describe('Search Works', () => {
.type('xxxxxxxxxxxx{enter}')
// timeout for the query results to return
.get('.alert-warning', { timeout: 60000 })
.should('contain', 'No works found.')
.should('contain', 'No results found.')
// no results count for zero results
.get('.member-results')
.should('not.exist')
Expand Down
8 changes: 8 additions & 0 deletions src/components/NoResults/NoResults.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react'
import Alert from 'react-bootstrap/Alert'

export default function NoResults() {
return (
<Alert variant="warning">No results found.</Alert>
)
}
28 changes: 4 additions & 24 deletions src/components/SearchOrganization/SearchOrganization.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
import React from 'react'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import Alert from 'react-bootstrap/Alert'
import { pluralize } from '../../utils/helpers'

import Pager from 'src/components/Pager/Pager'
import Error from 'src/components/Error/Error'
import NoResults from 'src/components/NoResults/NoResults'
import OrganizationMetadata from 'src/components/OrganizationMetadata/OrganizationMetadata'
import Loading from 'src/components/Loading/Loading'

Expand All @@ -23,34 +22,15 @@ export default function SearchOrganizations(props: Props) {

if (loading) return <Row><Loading /></Row>

if (error) return (
const organizations = data?.organizations
if (error || !organizations || organizations.nodes.length == 0) return (
Copy link
Member

Choose a reason for hiding this comment

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

Is there any reason we may want to keep the granularity of splitting the error out from no results and showing the error component? @jrhoads

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we ever want to in the future, we can split this up again.

<Row>
<Col md={{ span: 9, offset: 3 }}>
<Error title="An error occured." message={error.message} />
<NoResults />
</Col>
</Row>
)

const organizations = data?.organizations

if (!organizations || organizations.nodes.length == 0) return (
<Col md={{ span: 9, offset: 3 }}>
<div className="alert-works">
<Alert variant="warning">No organizations found.</Alert>
</div>
</Col>
)



if (!organizations || organizations.nodes.length == 0) return (
<Col md={{ span: 9, offset: 3 }}>
<div className="alert-works">
<Alert variant="warning">No organizations found.</Alert>
</div>
</Col>
)

const renderResults = () => {
const hasNextPage = organizations.pageInfo
? organizations.pageInfo.hasNextPage
Expand Down
18 changes: 4 additions & 14 deletions src/components/SearchPerson/SearchPerson.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import React from 'react'
import Loading from 'src/components/Loading/Loading'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import Alert from 'react-bootstrap/Alert'
import Error from 'src/components/Error/Error'
import PersonMetadata from 'src/components/PersonMetadata/PersonMetadata'
import Pager from 'src/components/Pager/Pager'
import NoResults from 'src/components/NoResults/NoResults'

import { QueryVar, useSearchPersonQuery } from 'src/data/queries/searchPersonQuery'

Expand All @@ -22,24 +21,15 @@ export default function SearchPerson(props: Props) {

if (loading) return <Row><Loading /></Row>

if (error) return (
const people = data?.people
if (error || !people || people.nodes.length == 0) return (
<Row>
<Col md={{ span: 9, offset: 3 }}>
<Error title="An error occured." message={error.message} />
<NoResults />
</Col>
</Row>
)

const people = data?.people

if (!people || people.nodes.length == 0) return (
<Col md={{ span: 9, offset: 3 }}>
<div className="alert-works">
<Alert variant="warning">No people found.</Alert>
</div>
</Col>
)


return (<>
<Row><Col md={{ span: 9, offset: 3 }}>
Expand Down
11 changes: 1 addition & 10 deletions src/components/SearchRepository/SearchRepository.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import Link from 'next/link'
import Pager from 'src/components/Pager/Pager'
import FairFilter from 'src/components/FairFilter/FairFilter'
import FacetList from 'src/components/FacetList/FacetList'
import Error from 'src/components/Error/Error'
import Loading from 'src/components/Loading/Loading'
import RepositoryMetadata from 'src/components/RepositoryMetadata/RepositoryMetadata'

Expand All @@ -28,18 +27,10 @@ export default function SearchRepositories({ variables }: Props) {

if (loading) return <Row><Loading /></Row>

if (error) return (
<Row>
<Col md={{ span: 9, offset: 3 }}>
<Error title="An error occured." message={error.message} />
</Col>
</Row>
)


const repositories = data?.repositories

if (!repositories || repositories.nodes.length == 0) return (
if (error || !repositories || repositories.nodes.length == 0) return (
<Col md={{ span: 9, offset: 3 }}>
<div className="alert-works">
<Alert variant="warning">
Expand Down
4 changes: 2 additions & 2 deletions src/components/SearchWork/SearchWork.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import React from 'react'
import Loading from '../Loading/Loading'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import Error from 'src/components/Error/Error'

import type { Works } from 'src/data/types'
import { QueryVar, useSearchDoiQuery } from 'src/data/queries/searchDoiQuery'
import { useSearchDoiFacetsQuery } from 'src/data/queries/searchDoiFacetsQuery'

import NoResults from 'src/components/NoResults/NoResults'
import WorksListing from 'src/components/WorksListing/WorksListing'
import { pluralize } from 'src/utils/helpers'

Expand All @@ -26,7 +26,7 @@ export default function SearchWork(props: Props) {
if (error) return (
<Row>
<Col md={{ span: 9, offset: 3 }}>
<Error title="An error occured." message={error.message} />
<NoResults />
</Col>
</Row>
)
Expand Down
10 changes: 4 additions & 6 deletions src/components/WorksListing/WorksListing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
import React from 'react'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import Alert from 'react-bootstrap/Alert'

import WorkFacets from 'src/components/WorkFacets/WorkFacets'
import WorkMetadata from 'src/components/WorkMetadata/WorkMetadata'
import { Works } from 'src/data/types'
import Loading from 'src/components/Loading/Loading'
import LoadingFacetList from 'src/components/Loading/LoadingFacetList'
import NoResults from 'src/components/NoResults/NoResults'

import Pager from '../Pager/Pager'
import WorksDashboard from '../WorksDashboard/WorksDashboard'
import Pager from 'src/components/Pager/Pager'
import WorksDashboard from 'src/components/WorksDashboard/WorksDashboard'
import SankeyGraph, { multilevelToSankey } from 'src/components/SankeyGraph/SankeyGraph'

interface Props {
Expand Down Expand Up @@ -63,9 +63,7 @@ export default function WorksListing({

const renderNoWorks = () => {
return (
<div className="alert-works">
<Alert variant="warning">No works found.</Alert>
</div>
<NoResults />
)
}

Expand Down
39 changes: 21 additions & 18 deletions src/data/queries/searchDoiFacetsQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,30 +60,33 @@ function convertToQueryData(json: any): QueryData {
}

export async function fetchDoisFacets(variables: QueryVar) {
try {
const options = {
method: 'GET',
headers: { accept: 'application/vnd.api+json' }
}
const searchParams = buildDoiSearchParams(variables)

const res = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/dois?${searchParams.toString()}`,
options
)
const json = await res.json()

const data = convertToQueryData(json)
return { data }
} catch (error) {
return { error }
const options = {
method: 'GET',
headers: { accept: 'application/vnd.api+json' }
}
const searchParams = buildDoiSearchParams(variables)

const res = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/dois?${searchParams.toString()}`,
options
)
const json = await res.json()
if(!res.ok) {
Copy link
Member

Choose a reason for hiding this comment

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

Do we want to do the error handling this way on all the REST fetches? @jrhoads

Copy link
Contributor Author

@jrhoads jrhoads Feb 4, 2025

Choose a reason for hiding this comment

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

Yeah. We had been catching the error. React/Tanstack query expects an error to be thrown. Otherwise it never populates the error state.

const errorMessage = json?.errors?.title || `Request for facets failed with status: ${res.status}`;
throw new Error(errorMessage);
}

const data = convertToQueryData(json)
return { data }
}

export function useSearchDoiFacetsQuery(variables: QueryVar) {
// eslint-disable-next-line no-unused-vars
const { cursor, ...vars } = variables
const { isPending, data, error } = useQuery({ queryKey: ['doiSearch', vars, 'facets'], queryFn: async () => fetchDoisFacets(variables) })
const { isPending, data, error } = useQuery({
queryKey: ['doiSearch', vars, 'facets'],
queryFn: async () => fetchDoisFacets(variables),
})

return { loading: isPending, data: data?.data, error }
}
Expand Down
35 changes: 18 additions & 17 deletions src/data/queries/searchDoiQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,24 +68,25 @@ function convertToQueryData(json: any): QueryData {
}

export async function fetchDois(variables: QueryVar) {
try {
const options = {
method: 'GET',
headers: { accept: 'application/vnd.api+json' }
}
const searchParams = buildDoiSearchParams(variables)

const res = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/dois?${searchParams.toString()}`,
options
)
const json = await res.json()

const data = convertToQueryData(json)
return { data }
} catch (error) {
return { error }
const options = {
method: 'GET',
headers: { accept: 'application/vnd.api+json' }
}
const searchParams = buildDoiSearchParams(variables)

const res = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/dois?${searchParams.toString()}`,
options
)
const json = await res.json()

if(!res.ok) {
const errorMessage = json?.errors?.title || `Request for dois failed with status: ${res.status}`;
throw new Error(errorMessage);
}

const data = convertToQueryData(json)
return { data }
}


Expand Down
Loading