Crosstalk-Solutions/project-nomad · error

${msg}

Error message

${msg}

What it means

DrugReferenceController.search wraps its search pipeline (query parsing + upstream drug reference search) in a try/catch and converts any exception into a 400 Bad Request carrying the raw error message. Because the catch is generic, the 400 does not necessarily mean a client mistake — infrastructure failures are also reported as 400. The real cause is always in the preceding [DrugReferenceController] search failed warn log.

Source

Thrown at admin/app/controllers/drug_reference_controller.ts:115

   * Returns a slim collapsed result list (brand+generic pairs).
   */
  async search({ request, response }: HttpContext) {
    try {
      const params = await request.validateUsing(searchDrugValidator)
      const results = await this.service.search(params.q, {
        productType: params.product_type,
        route: params.route,
        sort: params.sort,
        limit: params.limit,
        offset: params.offset,
        scope: params.scope,
      })
      return { results }
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err)
      logger.warn(`[DrugReferenceController] search failed: ${msg}`)
      return response.badRequest({ error: msg })
    }
  }

  /**
   * GET /api/drug-reference/status
   * Returns the live ingest status DTO.
   */
  async status({ response }: HttpContext) {
    try {
      const status = await this.service.getIngestStatus()
      return status
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err)
      logger.error(`[DrugReferenceController] status failed: ${msg}`)
      return response.internalServerError({ error: 'Could not read ingest status' })
    }
  }

  /**

View on GitHub (pinned to 0bd1c6f4f9)

Solutions

  1. Check server logs for the [DrugReferenceController] search failed warn with the actual message
  2. If the error mentions index/ingest, hit GET /api/drug-reference/status and run the ingest/download flow before searching
  3. Sanitize the q parameter and pagination values on the client
  4. Verify reference provider credentials/env config

Example fix

// before
fetch('/api/drug-reference/search?q=')
// after
if (!query.trim()) throw new Error('empty query')
fetch(`/api/drug-reference/search?q=${encodeURIComponent(query.trim())}&page=1&pageSize=20`)
Defensive patterns

Strategy: validation

Validate before calling

const q = query.trim()
if (q.length < 2) return showHint('Type at least 2 characters')
const page = Number.isInteger(pageNum) && pageNum > 0 ? pageNum : 1
const res = await fetch(`/api/drug-reference/search?q=${encodeURIComponent(q)}&page=${page}`)
if (!res.ok) return handleSearchError(await res.json())

Type guard

const isSearchErrorResponse = (b: unknown): b is { error: string } =>
  typeof b === 'object' && b !== null && typeof (b as any).error === 'string'

async function safeSearch(q: string) {
  const res = await fetch(`/api/drug-reference/search?q=${encodeURIComponent(q)}`)
  const body = await res.json().catch(() => null)
  if (!res.ok) return { results: [], error: isSearchErrorResponse(body) ? body.error : `HTTP ${res.status}` }
  return body as { results: unknown[] }
}

Try / catch

try {
  return await drugRef.search(q, page)
} catch (err) {
  // check ingest status before showing a hard error
  const status = await drugRef.status()
  if (!status.ingested) return { results: [], hint: 'Reference data not ingested yet' }
  throw err
}

Prevention

When it happens

Trigger: GET /api/drug-reference/search with a malformed or empty q, an unsupported page/pageSize value, or when the underlying reference service throws (empty index, ingest never ran, upstream provider error). Called by the results endpoint, so navigating to search results with a bad or stale query triggers it.

Common situations: Searching before the drug-reference ingest has completed (empty index); passing non-numeric pagination params; reference provider API key missing; stale frontend sending a query format from an older API version.

Related errors


AI-assisted analysis of Crosstalk-Solutions/project-nomad@0bd1c6f4f9 (2026-08-27). Data as JSON: /api/errors/5603dc3abacb2466. Report an issue: GitHub.