Skip to content

Commit

Permalink
fix(structure): provide better error handling if orderings contain in…
Browse files Browse the repository at this point in the history
…valid field (#5709)

* fix(structure): provide better error handling if orderings contain invalid field

* chore: fixed lint issue

* chore: fixed lint issue again

* fix(structure): provide better error handling if orderings contain invalid field

* fix(structure): provide better error handling if orderings contain invalid field

* fix(structure): add comment explaining why we are calling this method
  • Loading branch information
jtpetty authored Mar 1, 2024
1 parent 9ed5cca commit 4926b78
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
} from 'sanity'
import {getSearchableTypes, getSearchTypesWithMaxDepth} from 'sanity/_internalBrowser'

import {getExtendedProjection} from '../../structureBuilder/util/getExtendedProjection'
import {type SortOrder} from './types'

interface ListenQueryOptions {
Expand Down Expand Up @@ -90,7 +91,14 @@ export function listenSearchQuery(options: ListenQueryOptions): Observable<Sanit
mergeMap((typeNames: string[]) => {
const types = getSearchTypesWithMaxDepth(
getSearchableTypes(schema).filter((type) => {
return typeNames.includes(type.name)
if (typeNames.includes(type.name)) {
// make a call to getExtendedProjection in strict mode to verify that all fields are
// known. This method will throw an exception if there are any unknown fields specified
// in the sort by list
getExtendedProjection(type, sort.by, true)
return true
}
return false
}),
maxFieldDepth,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {type SchemaType, type SortOrderingItem} from '@sanity/types'

const IMPLICIT_FIELDS = ['_id', '_type', '_createdAt', '_updatedAt', '_rev']
const IMPLICIT_SCHEMA_TYPE_FIELDS = ['_id', '_type', '_createdAt', '_updatedAt', '_rev']

// Takes a path array and a schema type and builds a GROQ join every time it enters a reference field
function joinReferences(schemaType: SchemaType, path: string[]): string {
function joinReferences(schemaType: SchemaType, path: string[], strict: boolean = false): string {
const [head, ...tail] = path

if (!('fields' in schemaType)) {
Expand All @@ -12,14 +12,14 @@ function joinReferences(schemaType: SchemaType, path: string[]): string {

const schemaField = schemaType.fields.find((field) => field.name === head)
if (!schemaField) {
if (!IMPLICIT_FIELDS.includes(head)) {
// eslint-disable-next-line no-console
console.warn(
'The current ordering config targeted the nonexistent field "%s" on schema type "%s". It should be one of %o',
head,
schemaType.name,
schemaType.fields.map((field) => field.name),
)
if (!IMPLICIT_SCHEMA_TYPE_FIELDS.includes(head)) {
const errorMessage = `The current ordering config targeted the nonexistent field "${head}" on schema type "${schemaType.name}". It should be one of ${schemaType.fields.map((field) => field.name).join(', ')}`
if (strict) {
throw new Error(errorMessage)
} else {
// eslint-disable-next-line no-console
console.warn(errorMessage)
}
}
return ''
}
Expand All @@ -34,6 +34,12 @@ function joinReferences(schemaType: SchemaType, path: string[]): string {
return tail.length > 0 ? `${head}${tailWrapper}` : head
}

export function getExtendedProjection(schemaType: SchemaType, orderBy: SortOrderingItem[]): string {
return orderBy.map((ordering) => joinReferences(schemaType, ordering.field.split('.'))).join(', ')
export function getExtendedProjection(
schemaType: SchemaType,
orderBy: SortOrderingItem[],
strict: boolean = false,
): string {
return orderBy
.map((ordering) => joinReferences(schemaType, ordering.field.split('.'), strict))
.join(', ')
}

0 comments on commit 4926b78

Please sign in to comment.