yikart/AiToEarn · warning · BadRequestException
邮箱参数不能为空
Error message
邮箱参数不能为空
What it means
The GET /youtube/auth/url endpoint requires a 'mail' query parameter that identifies which user/email the YouTube OAuth authorization is for. NestJS BadRequestException (HTTP 400) is thrown when the mail parameter is absent or empty.
Source
Thrown at project/aitoearn-electron/server/src/modules/plat/youtube/youtube.controller.ts:56
private readonly youtubeService: YoutubeService,
private readonly youtubeAuthService: YouTubeAuthService,
) {}
@ApiOperation({ summary: '测试' })
@Public()
@Get('test')
async getTest() {
const res = "success";
return res;
}
@ApiOperation({ summary: '获取YouTube授权URL' })
@Get('auth/url')
async getAuthUrl(
@GetToken() systemToken: TokenInfo,
@Query('mail') mail: string) {
if (!mail) {
throw new BadRequestException('邮箱参数不能为空');
}
// async getAuthUrl(@GetToken() token: TokenInfo) {
// // mail = token.id
// // if (!mail) {
// // throw new BadRequestException('邮箱参数不能为空');
// // }
return this.youtubeAuthService.getAuthorizationUrl(mail, systemToken.id);
}
@ApiOperation({ summary: '处理YouTube授权回调' })
@Public()
@Get('auth/callback')
async handleAuthCallback(
// @GetToken() systemToken: TokenInfo,
@Query('code') code: string,
@Query('state') state: string,
// @Query('userId') userId: string,View on GitHub (pinned to d3aa8bea5b)
Solutions
- Append the mail query parameter: GET /youtube/auth/url?mail=user@example.com
- Verify the frontend reads the current user's email (not undefined) before calling the endpoint
- Ensure the query string is properly encoded (encodeURIComponent for emails with special chars)
Example fix
// before
const res = await fetch('/api/plat/youtube/auth/url');
// after
const res = await fetch(`/api/plat/youtube/auth/url?mail=${encodeURIComponent(userEmail)}`); Defensive patterns
Strategy: validation
Validate before calling
if (!mail || typeof mail !== 'string' || !mail.includes('@')) {
throw new Error('mail query parameter is required before calling /youtube/auth/url');
} Type guard
function hasMail(q: Record<string, unknown>): q is { mail: string } {
return typeof q.mail === 'string' && q.mail.trim().length > 0;
} Try / catch
try {
const { data } = await api.get('/plat/youtube/auth/url', { params: { mail: userEmail } });
} catch (e) {
if (e.response?.status === 400 && String(e.response.data?.message).includes('邮箱参数')) {
// prompt user to provide/select an email and retry
}
} Prevention
- Always read the authenticated user's email from session/token before building the request
- encodeURIComponent the mail value
- Add client-side form validation for required email
- Keep integration docs listing required query params for the endpoint
When it happens
Trigger: Calling GET /api/plat/youtube/auth/url without ?mail= or with mail= (empty string), typically when constructing the authorization URL request programmatically and forgetting the query parameter.
Common situations: Frontend calls the endpoint after login but does not propagate the user's email; curl/Postman testing omits the query param; URL built with a template variable that was undefined and serialized as empty.
Related errors
- 只能选择一个参数: handle, userName, id 或 mine
- 只能选择一个参数: channelId, id, mine
- 只能选择一个参数: allThreadsRelatedToChannelId, id, videoId
- 只能选择一个参数: regionCode, id
- Invalid ObjectId
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/d8b953258adabded.
Report an issue: GitHub.