gRPC循环结构转JSON报错问题求助
解决NestJS中"Converting circular structure to JSON"登录报错问题
问题原因
API网关的login方法中调用return res.json(...)时,res.json()会返回Response对象本身。该对象内部包含Socket、WritableState等存在循环引用的属性,NestJS尝试对返回值进行JSON序列化时,就会触发循环结构转换错误。尽管客户端能正常收到响应,但控制台会输出错误日志。
解决方案
方案一:手动发送响应,不返回Response对象
修改API网关的login方法,发送响应后不返回任何值(将返回类型改为Promise<void>):
@Post('login') @HttpCode(200) async login(@Body() loginData: Login, @Res({ passthrough: true }) res: Response): Promise<void> { try { const user = await firstValueFrom(this.userService.Login(loginData)); console.log(user); res.cookie('refreshToken', user.refreshToken, { httpOnly: true, sameSite: true, }); delete user.refreshToken; // 直接发送响应,不返回该对象 res.json({ message: 'Login successful.', data: user }); } catch (error) { throw new Error('Login failed'); } }
方案二:利用NestJS原生响应机制,返回纯数据对象
保持passthrough: true用于设置Cookie,直接返回要响应的纯数据对象,让NestJS自动处理JSON序列化:
@Post('login') @HttpCode(200) async login(@Body() loginData: Login, @Res({ passthrough: true }) res: Response): Promise<any> { try { const user = await firstValueFrom(this.userService.Login(loginData)); console.log(user); res.cookie('refreshToken', user.refreshToken, { httpOnly: true, sameSite: true, }); delete user.refreshToken; // 直接返回响应内容,由NestJS处理序列化 return { message: 'Login successful.', data: user }; } catch (error) { throw new Error('Login failed'); } }
额外说明
两种方案都能解决循环引用报错问题,方案二更符合NestJS的开发规范,推荐使用。
内容的提问来源于stack exchange,提问作者John Oliver
相关产品推荐
相关产品推荐

