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

Bad request error is thrown instead of AuthenticationError #4207

Open
rimselis opened this issue Aug 28, 2023 · 9 comments · Fixed by #4208
Open

Bad request error is thrown instead of AuthenticationError #4207

rimselis opened this issue Aug 28, 2023 · 9 comments · Fixed by #4208

Comments

@rimselis
Copy link

What is the problem?

Error: Bad request (400) error is thrown when query is set to be authorized.

I have created a simple query on a new project to return an empty array and used it on the index page's UserInfo component.

import { resolver } from "@blitzjs/rpc";

export default resolver.pipe(
  // resolver.authorize(),
  async ({}) => {
    return [];
  }
);

When resolver.authorize() is commented out, I can successfully use the query in component
const [users] = useQuery(getUsers, {}) and it returns an empty array with no issues. But when I uncomment resolver.authorize(), a 400: Bad request error is shown. By default, blitz creates a RootErrorFallback component to be used in ErrorBoundary component as fallback.

RootErrorFallback component checks for different types of errors:

  if (error instanceof AuthenticationError) {
    return ...
  } else if (error instanceof AuthorizationError) {
    return ...
  } else {
    return ...
  }

For some reason, the AuthenticationError is skipped and the default/fallback else statement is returning the ErrorComponent.

On the server-side logs, I can see the correct issue ([AuthenticationError: You must be logged in to access this] {statusCode: 401}) being logged, but on the client side it's just an Uncaught Error: Bad Request error

Paste all your error logs here:

[Rendering Suspense fallback...: DYNAMIC_SERVER_USAGE] {
  digest: 'DYNAMIC_SERVER_USAGE'
}
2023-08-28 15:51:59.147	INFO	[blitz-rpc]	getCurrentUser() Starting with input: null
2023-08-28 15:51:59.147	DEBUG	[blitz-rpc]	getCurrentUser() Result: null
2023-08-28 15:51:59.147	DEBUG	[blitz-rpc]	getCurrentUser() Next.js serialization:0ms
2023-08-28 15:51:59.147	INFO	[blitz-rpc]	getCurrentUser() Finished: resolver:0ms serializer:0ms total:0ms
2023-08-28 15:51:59.162	INFO	[blitz-rpc]	getUsers() Starting with input: {}
[AuthenticationError: You must be logged in to access this] {
  statusCode: 401
}


Error while processing the request
TypeError: Cannot read properties of undefined (reading 'map')
    at prettyFormatErrorObj (/.../blitz-test/node_modules/tslog/dist/cjs/runtime/nodejs/index.js:95:47)
    at maskedArgs.reduce.args (/.../blitz-test/node_modules/tslog/dist/cjs/runtime/nodejs/index.js:89:43)
    at Array.reduce (<anonymous>)
    at Object.prettyFormatLogObj (/.../blitz-test/node_modules/tslog/dist/cjs/runtime/nodejs/index.js:88:23)
    at Logger.log (/.../blitz-test/node_modules/tslog/dist/cjs/BaseLogger.js:111:77)
    at Logger.error (/.../blitz-test/node_modules/tslog/dist/cjs/index.js:51:22)
    at /.../blitz-test/node_modules/@blitzjs/rpc/dist/index-server.cjs:326:15
    at Generator.throw (<anonymous>)
    at rejected (/.../blitz-test/node_modules/@blitzjs/rpc/dist/index-server.cjs:127:29)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Browser console:

Uncaught Error: Bad Request
[rpc.mjs:81](webpack://_N_E/node_modules/@blitzjs/rpc/dist/chunks/rpc.mjs?506a)
    promise rpc.mjs:81
    InterpretGeneratorResume self-hosted:1455
    next self-hosted:1376
    __async rpc.mjs:23
    __async rpc.mjs:7
    promise rpc.mjs:76
    (Async: promise callback)
    httpClient rpc.mjs:76
    InterpretGeneratorResume self-hosted:1455
    next self-hosted:1376
    fulfilled rpc.mjs:10
    (Async: promise callback)
    step rpc.mjs:22
    __async rpc.mjs:23
    __async rpc.mjs:7
    httpClient rpc.mjs:37
    queryFn index.mjs:71
    fetchFn query.mjs:252
    run retryer.mjs:97
    createRetryer retryer.mjs:145
    fetch query.mjs:306
    fetchOptimistic queryObserver.mjs:150
    fetchOptimistic suspense.mjs:12
    useBaseQuery useBaseQuery.mjs:47
    useQuery useQuery.mjs:6
    useQuery index.mjs:69
    UserInfo index.tsx:18
    React 13
    NextJS 2
The above error occurred in the <UserInfo> component:

UserInfo@webpack-internal:///./src/pages/index.tsx:32:103
Suspense
div
div
div
main
div
Layout@webpack-internal:///./src/core/layouts/Layout.tsx:12:33
Home
AuthRoot@webpack-internal:///./node_modules/@blitzjs/auth/dist/chunks/index.mjs:387:15
_a@webpack-internal:///./node_modules/@blitzjs/next/dist/chunks/index-browser.mjs:176:7
WithRouterWrapper@webpack-internal:///./node_modules/next/dist/client/with-router.js:17:43
MyApp@webpack-internal:///./src/pages/_app.tsx:49:38
Hydrate@webpack-internal:///./node_modules/@tanstack/react-query/build/lib/Hydrate.mjs:29:17
QueryClientProvider@webpack-internal:///./node_modules/@tanstack/react-query/build/lib/QueryClientProvider.mjs:46:29
BlitzProvider@webpack-internal:///./node_modules/@blitzjs/next/dist/chunks/index-browser.mjs:109:23
BlitzOuterRoot@webpack-internal:///./node_modules/@blitzjs/next/dist/chunks/index-browser.mjs:465:105
WithSuperJSON@webpack-internal:///./node_modules/@blitzjs/next/dist/chunks/index-browser.mjs:103:104
PathnameContextProviderAdapter@webpack-internal:///./node_modules/next/dist/shared/lib/router/adapters.js:74:44
ErrorBoundary@webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:305:63
ReactDevOverlay@webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:854:908
Container@webpack-internal:///./node_modules/next/dist/client/index.js:83:1
AppContainer@webpack-internal:///./node_modules/next/dist/client/index.js:187:25
Root@webpack-internal:///./node_modules/next/dist/client/index.js:365:37

React will try to recreate this component tree from scratch using the error boundary you provided, _a.

Paste all relevant code snippets here:

const [users] = useQuery(getUsers, {})
import { resolver } from "@blitzjs/rpc";

export default resolver.pipe(
  // resolver.authorize(),
  async ({}) => {
    return [];
}
);
export default async function getUsers(input, ctx) {
  // ctx.session.$authorize();
  return [];
}

What are detailed steps to reproduce this?

  1. Create new Blitz project (TS, Full, yarn, hook form)
  2. Create a new query file src/users/queries/getUsers.ts
  3. Write the query to return anything (array, object, boolean, etc.)
  4. Import and the query in UserInfo component via useQuery from @blitzjs/rpc
  5. Start the project (blitz dev), go to localhost, create a user/login - everything should work
  6. Uncomment resolver.authorize(), or ctx.session.$authorize(); in query file
  7. Log out the user
  8. ErrorComponent will be shown instead of Error: You are not authenticated

Run blitz -v and paste the output here:

Blitz version: 2.0.0-beta.32 (global)
Blitz version: 2.0.0-beta.32 (local)
macOS Ventura | darwin-arm64 | Node: v18.16.1


 Package manager: npm

  System:
    OS: macOS 13.4.1
    CPU: (8) arm64 Apple M2
    Memory: 874.50 MB / 24.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.16.1 - ~/.nvm/versions/node/v18.16.1/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v18.16.1/bin/yarn
    npm: 9.5.1 - ~/.nvm/versions/node/v18.16.1/bin/npm
  npmPackages:
    @blitzjs/auth: 2.0.0-beta.32 => 2.0.0-beta.32
    @blitzjs/next: 2.0.0-beta.32 => 2.0.0-beta.32
    @blitzjs/rpc: 2.0.0-beta.32 => 2.0.0-beta.32
    @prisma/client: 4.6.1 => 4.6.1
    blitz: 2.0.0-beta.32 => 2.0.0-beta.32
    next: 13.4.5 => 13.4.5
    prisma: 4.6.1 => 4.6.1
    react: 18.2.0 => 18.2.0
    react-dom: 18.2.0 => 18.2.0
    typescript: ^4.8.4 => 4.9.5

Please include below any other applicable logs and screenshots that show your problem:

Screenshot 2023-08-28 at 4 02 52 pm

@rimselis rimselis added kind/bug Something isn't working status/triage labels Aug 28, 2023
@rodobre
Copy link
Contributor

rodobre commented Aug 29, 2023

Experiencing the same issue on 2.0.0-beta.32. Same blitz version output as @rimselis

@rimselis
Copy link
Author

Tested it from blitz@2.0.0-beta.28 to blitz@2.0.0-beta.32. Issue happens only on blitz@2.0.0-beta.32.

@jrausell
Copy link

jrausell commented Aug 29, 2023

Same issue on 2.0.0-beta.32.

Tested downgrading to blitz@2.0.0-beta.28 as commented by Rimselis, and also .beta-31. In both appear but the expected message "Error: You are not authenticated"

@siddhsuresh
Copy link
Member

Hey @rimselis, could you add an explicit Superjson registration in your blitz-sever.ts file and check.

//blitz-server.ts
...
  SuperJson.registerClass(AuthenticationError, {
    identifier: "BlitzAuthenticationError",
    allowProps: ["name", "message", "code", "statusCode", "meta", "url"],
  })

@mjyoung
Copy link

mjyoung commented Sep 7, 2023

I'm on 2.0.0-beta.33 and am still getting a 400 instead of the expected 401 AuthenticationError. This only occurs in my production env and not in local dev.

This occurs when I am using resolver.authorize(Role.Admin) for example.

Are you sure it was fixed @rodobre ? This is what I see instead of the expected error fallback:
image

@siddhsuresh siddhsuresh reopened this Sep 8, 2023
Toolkit automation moved this from Done to In progress Sep 8, 2023
@aaly00
Copy link

aaly00 commented Sep 9, 2023

I am seeing the same issue. For some reason it only happens on my machine, and doesn't happen in production on Vercel. Upgrading to beta.33 fixes the issue. @mjyoung Did you make sure to update all blitz packages ? The fix is in the RPC package.
image

@mjyoung
Copy link

mjyoung commented Sep 12, 2023

Yes, all packages are updated to 2.0.0-beta.33:

    "@blitzjs/auth": "2.0.0-beta.33",
    "@blitzjs/next": "2.0.0-beta.33",
    "@blitzjs/rpc": "2.0.0-beta.33",

@rimselis
Copy link
Author

The initial issue seems to be fixed with 2.0.0-beta.33 (checked both with resolver.authorize() and with ctx.session.$authorize()) on the same fresh project. Thank you!

Not sure if I should close this as there are open questions in the comments.

@mjyoung
Copy link

mjyoung commented Sep 13, 2023

Not sure what I'm doing wrong then. I'm on 2.0.0-beta.33 and in production, my error boundaries do not trigger on instanceof AuthenticationError and instanceof AuthorizationError.

Above still doesn't work even if I add the following to blitz-server:

SuperJSON.registerClass(AuthenticationError);
SuperJSON.registerClass(AuthorizationError);

Can I use instanceof or do I need to do if (error.name === 'AuthenticationError)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Toolkit
In progress
Development

Successfully merging a pull request may close this issue.

7 participants