Skip to content

[Start] Function middleware: try/catch doesn't catch errors from next() - must check result.error instead #6418

@alexander-zuev

Description

@alexander-zuev

Description

Function middleware (type: 'function') cannot catch errors from inner middleware/handlers using try/catch. The docs show this pattern, but it doesn't work for function middleware.

Reproduction

// This does NOT work - catch block never fires
const errorMiddleware = createMiddleware({ type: 'function' }).server(async ({ next }) => {
  try {
    return await next()
  } catch (error) {
    // Never reached when inner middleware/handler throws
    console.log('caught', error)
    throw error
  }
})

Root Cause

In createServerFn.js, userNext catches errors and returns them as { error } instead of throwing:

// Line 154-161
const userNext = async (userCtx = {}) => {
  try {
    return await callNextMiddleware(nextCtx);
  } catch (error) {
    return { ...nextCtx, error };  // Returns, doesn't throw
  }
};

Working Solution

Must check result.error instead:

const errorMiddleware = createMiddleware({ type: 'function' }).server(async ({ next }) => {
  const result = await next()
  
  if (result.error) {
    // Handle error here
    return { ...result, error: new Error('Sanitized message') }
  }
  
  return result
})

Issues

  1. Docs show try/catch (observability guide) but that's for request middleware, not function middleware
  2. TypeScript types don't include error on the result - requires cast: (await next()) as { error?: Error }
  3. Ambiguity - unclear when to use try/catch vs result.error

Questions

  1. Is checking result.error the intended pattern for function middleware error handling?
  2. Should TypeScript types include error property on FunctionServerResultWithContext?
  3. Should docs clarify the difference between request middleware and function middleware error handling?

Environment

  • @tanstack/react-start: 1.149.1
  • @tanstack/start-client-core: 1.149.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions