Error Handling

Authentication fails. Here's what happens and how to handle it.

Invalid or expired token

Status: 401 Unauthorized

What happens: Request is rejected before reaching your handler.

@Get('protected')
@Authentication()
getProtected() {
  // This never runs if token is invalid/expired
  return { data: 'secret' };
}

You don't need to handle this in your code. The guard does it automatically.

On the frontend: Refresh the token and retry.

Wrong token type

When: You use @CognitoIdUser() but send an access token (or vice versa).

Status: 401 Unauthorized

// This throws if you send an access token
@Get('profile')
@Authentication()
getProfile(@CognitoIdUser() user: CognitoIdTokenPayload) {
  return user;
}

Fix: Use @CognitoUser() (works with both) or send the correct token type.

Missing groups

Status: 403 Forbidden

The @Authorization decorator handles this automatically:

@Get('admin')
@Authorization(['admin'])
getAdmin() {
  return { data: 'admin only' };
}

User without the 'admin' group gets a 403. No code needed.

No token

Status: 401 Unauthorized

Exception: On @PublicRoute(), request goes through with user = undefined.

@Get('welcome')
@PublicRoute()
welcome(@CognitoUser() user?: CognitoJwtPayload) {
  return user ? `Hello ${user.username}` : 'Hello guest';
}

Configuration errors

When: Wrong User Pool ID, network issues fetching JWKS keys.

Status: 500 Internal Server Error

Check your config:

CognitoAuthModule.register({
  jwtVerifier: {
    userPoolId: 'us-east-1_XXXXX',  // ← Verify this
    clientId: 'your-client-id',
    tokenUse: 'access',
  },
})

Custom error responses

Catch all auth errors globally:

import { ExceptionFilter, Catch, ArgumentsHost, UnauthorizedException } from '@nestjs/common';

@Catch(UnauthorizedException)
export class AuthExceptionFilter implements ExceptionFilter {
  catch(exception: UnauthorizedException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();

    response.status(401).json({
      statusCode: 401,
      message: 'Authentication failed',
      timestamp: new Date().toISOString(),
    });
  }
}

Register it:

import { APP_FILTER } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: AuthExceptionFilter,
    },
  ],
})
export class AppModule {}