question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

RC 5 breaks useRequestHeaders

See original GitHub issue

My app worked perfectly prior to RC5. After the update, my app is broken when running both npm run dev and npm run build.

It seems useRequestHeaders no longer works within a plugin. It returns: { host: undefined }. As a result, the rest of my app breaks.

This is part of the error log that I’m seeing:

[Vue warn]: Component <Anonymous> is missing template or render function.
[nuxt] [request error] Cannot read properties of null (reading 'value')
  at ReactiveEffect.fn (./.output/server/chunks/app/server.mjs:55842:23)  
  at ReactiveEffect.run (./.output/server/chunks/handlers/renderer.mjs:1389:25)  
  at ComputedRefImpl.get value [as value] (./.output/server/chunks/handlers/renderer.mjs:2277:39)  
  at Object.unref (./.output/server/chunks/handlers/renderer.mjs:2188:29)  
  at ./.output/server/chunks/app/server.mjs:55869:91  
  at renderComponentSubTree (./.output/server/chunks/handlers/renderer.mjs:10591:13)  
  at ./.output/server/chunks/handlers/renderer.mjs:10523:29  
  at processTicksAndRejections (node:internal/process/task_queues:96:5)  
  at async unrollBuffer (./.output/server/chunks/handlers/renderer.mjs:10743:24)  
  at async unrollBuffer (./.output/server/chunks/handlers/renderer.mjs:10749:24)
[nitro] [dev] [unhandledRejection] Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
[Vue warn]: Component <Anonymous> is missing template or render function.
[nuxt] [request error] Cannot read properties of null (reading 'value')
  at ReactiveEffect.fn (./.output/server/chunks/app/server.mjs:55842:23)  
  at ReactiveEffect.run (./.output/server/chunks/handlers/renderer.mjs:1389:25)  
  at ComputedRefImpl.get value [as value] (./.output/server/chunks/handlers/renderer.mjs:2277:39)  
  at Object.unref (./.output/server/chunks/handlers/renderer.mjs:2188:29)  
  at ./.output/server/chunks/app/server.mjs:55869:91  
  at renderComponentSubTree (./.output/server/chunks/handlers/renderer.mjs:10591:13)  
  at ./.output/server/chunks/handlers/renderer.mjs:10523:29  
  at processTicksAndRejections (node:internal/process/task_queues:96:5)  
  at async unrollBuffer (./.output/server/chunks/handlers/renderer.mjs:10743:24)  
  at async unrollBuffer (./.output/server/chunks/handlers/renderer.mjs:10749:24)
[nitro] Error while generating error response FetchError: 302  (/__nuxt_error?url=/login&statusCode=500&statusMessage=Internal+Server+Error&message=Cannot+read+properties+of+null+(reading+'value')&description&data)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Object.errorhandler [as onError] (<REDACTED>/.output/server/chunks/nitro/node-server.mjs:322:16)
    at async Server.nodeHandler (<REDACTED>/.output/server/node_modules/h3/dist/index.mjs:373:9)

Here is a subset of the code for my auth plugin:

export default defineNuxtPlugin(() => {
  const token = useCookie('token')
  const isLoggedIn = useState('isLoggedIn', () => !!token.value)
  const user = useState<Partial<IAuthUser>>('user', () => null)
  
  const { API_URL: baseURL } = useRuntimeConfig()

  addRouteMiddleware('global-auth', async (to) => {
    if (!to.path.includes('/login')) {
      try {
        await login()
      } catch (e) {
        return logout()
      }
    } else if (isLoggedIn.value && to.path.includes('/login')) {
      try {
        await login()
        return '/'
      } catch (e) {
        return logout()
      }
    }
  }, { global: true })

  const getTokenViaSSO = async () => {
    try {
      const reqHeaders = useRequestHeaders()
      const headers = []
      const method = { name: null }

      if (reqHeaders.authorization) {
        method.name = 'basic'
        headers.push(...['authorization'])
      }

      if (!token.value) {
        const data = await $fetch<any>('/users/login', {
          baseURL,
          method: 'post',
          onRequest({ options }) {
            if (process.server) {
              options.headers = useRequestHeaders(headers);
            }
            return Promise.resolve()
          },
          body: { method }
        })
        token.value = data.token
      }
    } catch(e) {
      throw Error(e)
    }
  }

  const getTokenViaForm = async (username: string, password: string) => {
    try {
      if (!token.value) {
        const data = await $fetch<any>('/users/login', {
          baseURL,
          method: 'post',
          body: {
            method: { name: 'form' },
            username,
            password
          }
        })
        token.value = data.token
      }
    } catch(e) {
      throw Error(e)
    }
  }

  const getUser = async () => {
    try {
      const data = await $fetch<any>('/users/me', {
        baseURL,
        method: 'get',
        headers: {
          'x-token': token.value
        },
      })
      user.value = data
      isLoggedIn.value = true
    } catch(e) {
      throw Error(e)
    }
  }

  const resetAuthValues = () => {
    token.value = null
    user.value = null
    isLoggedIn.value = false
  }

  const logout = async () => {
    resetAuthValues()
    return navigateTo('/login')
  }

  const login = async (username?: string, password?: string) => {
    try {
      if (username && password) {
        if (!token.value) await getTokenViaForm(username, password)
      } else {
        if (!token.value) await getTokenViaSSO()
      }
      if (!user.value) await getUser()
      if (username && password) return navigateTo('/')
    } catch (e) {
      throw Error(e)
    }
  }

  return {
    provide: {
      auth: {
        token,
        isLoggedIn,
        user,
        getTokenViaForm,
        getTokenViaSSO,
        getUser,
        login,
        logout
      }
    }
  }
})

Again, this all worked great in RC 4 and below. After upgrading to RC 5, everything blows up.

_Originally posted by @jshimkoski in https://github.com/nuxt/framework/discussions/5885#discussioncomment-3140477_

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
jshimkoskicommented, Jul 14, 2022

So, it’s been a long day but I finally tracked down the issue.

It is related to #5895.

I am use useFetch at the core of my API plugin. Once I set a unique key, the explosion stops.

const apiFetch = (method) => {
  return async (path: string, opts?: Omit<FetchOptions, 'method'>) => {
    const fetchOptions = {
      key: hash(['api-fetch', path, opts]),
      baseURL,
      ...opts,
      method: 'get',
      headers: {
        'x-token': token.value
      },
    }
    return useFetch(path, fetchOptions)
  }
}

Will look into replacing it with useState and $fetch, however, I would miss the capabilities that useFetch provides: data, pending, refresh, error.

0reactions
jshimkoskicommented, Jul 14, 2022

Quick update: I’ve been digging through the code and, as you guessed, the issue doesn’t appear to be useRequestHeaders.

I have another plugin that is dependent on the $auth values ($auth.user.value in particular) being present (I use this other plugin for all API calls).

What I’m seeing so far is that $auth.user.value returned in the API plugin as null (even when it is properly set in the auth plugin, which triggers an API error, which in turn triggers other errors, setting off a domino effect.

I’m still digging and will keep you updated. If it does turn out to be a Nuxt issue, I’ll provide a reproduction. Just very odd that this didn’t happen until RC 5. If I downgrade to RC 4 and below, the app works without issue.

Sorry for the time this might take… this app is huge… (200+ components).

Read more comments on GitHub >

github_iconTop Results From Across the Web

nuxt/framework v3.0.0-rc.5 on GitHub - NewReleases.io
New release nuxt/framework version v3.0.0-rc.5 on GitHub. ... This release contains slight breaking changes. Please check the linked pull requests for notes ...
Read more >
@nuxt/vite-builder - NPM Package Overview - Socket
Breaking Changes. cli: Setup nuxt globally with nuxt test (#4578); nuxt: Only add $f fetch prefix to auto-keys (#8852); test-utils: Use ...
Read more >
RC-5 | Loop Station - BOSS
Step up to the RC-5 and prime your pedalboard with maximum looping range. Capture sound with premium 32-bit quality, navigate parameters and monitor...
Read more >
Browse API - eBay Developers Program
For example, if the keyword is brakes and compatibility-filter=Year:2018 ... https://www.ebay.com/itm/2021-New-RC-Drone-4k-HD-Wide-Angle-Camera-WIFI-FPV- ...
Read more >
Boss RC-5 Loop Station Review
Don't get me wrong – the design of the pedal is great. If it isn't broken, why fix it? But under the hood...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found