yikart/AiToEarn · error · Error

无法生成授权URL

Error message

无法生成授权URL

What it means

getAuthorizationUrl builds the Google OAuth2 consent URL using GOOGLE_CONFIG.WEB_CLIENT_ID and WEB_RENDER_URL from ConfigService, then returns {url}. Any exception during construction (undefined config values producing invalid URL, redis service errors when storing the state key) is replaced by a generic Error('无法生成授权URL'), discarding the original cause from the thrown message.

Source

Thrown at project/aitoearn-electron/server/src/modules/plat/youtube/youtube.auth.service.ts:120

      const params = new URLSearchParams({
        scope: youtubeScopes.join(" "),
        access_type: "offline",
        include_granted_scopes: "true",
        response_type: "code",
        state: encodedState,
        redirect_uri: `${this.webRenderBaseUrl}/api/plat/youtube/auth/callback`,
        client_id: this.webClientId,
        prompt: "consent",  // 强制要求用户确认授权,以便我们能够获取refresh_token
        // login_hint: userId,
      });

      const authUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth');
      authUrl.search = params.toString();

      return {url: authUrl.toString()};
    } catch (error) {
      console.error('Error generating auth URL:', error);
      throw new Error('无法生成授权URL');
    }
  }

  /**
   * 获取用户的YouTube访问令牌
   * @param accountId 账号ID
   * @returns 访问令牌
   */
  async getUserAccessToken(accountId: string): Promise<string> {
    console.log("accountId:--", accountId);
    const accountTokenInfo = await this.AccountTokenModel.findOne({accountId: accountId});

    // if (!res) return '';

    // // 剩余时间
    // const overTime = res.expires_in;

    // if (overTime < 60 * 60 && overTime > 0) {

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Check that GOOGLE_CONFIG.WEB_CLIENT_ID and GOOGLE_CONFIG.WEB_RENDER_URL are set in the server env before calling this method.
  2. Verify Redis is reachable, since the state key write happens before URL building.
  3. Improve the catch to rethrow the original error (throw new Error(`无法生成授权URL: ${error.message}`)) to expose the root cause.
  4. Validate the generated URL with new URL() and assert client_id is a non-empty string.
  5. Confirm the env file loaded by ConfigService matches the running environment (dev vs prod).

Example fix

// before
} catch (error) {
  console.error('Error generating auth URL:', error);
  throw new Error('无法生成授权URL');
}
// after
} catch (error) {
  console.error('Error generating auth URL:', error);
  throw new Error(`无法生成授权URL: ${(error as Error).message}`);
}
Defensive patterns

Strategy: validation

Validate before calling

function assertGoogleConfig(config: ConfigService) {
  const clientId = config.get<string>('GOOGLE_CONFIG.WEB_CLIENT_ID')
  const baseUrl = config.get<string>('GOOGLE_CONFIG.WEB_RENDER_URL')
  if (!clientId || !baseUrl) throw new Error('GOOGLE_CONFIG.WEB_CLIENT_ID / WEB_RENDER_URL not configured')
  new URL(baseUrl) // throws on malformed base URL
}

Type guard

const hasGoogleConfig = (c: unknown): c is { WEB_CLIENT_ID: string; WEB_RENDER_URL: string } =>
  typeof c === 'object' && c !== null &&
  typeof (c as any).WEB_CLIENT_ID === 'string' && (c as any).WEB_CLIENT_ID.length > 0 &&
  typeof (c as any).WEB_RENDER_URL === 'string'

Try / catch

try {
  const { url } = await youtubeAuthService.getAuthorizationUrl(mail, userId)
} catch (e) {
  if (e.message === '无法生成授权URL') {
    // root cause is hidden; check GOOGLE_CONFIG env and Redis connectivity, then fail fast
    throw new Error('YouTube OAuth config missing or Redis unavailable')
  }
  throw e
}

Prevention

When it happens

Trigger: GOOGLE_CONFIG.WEB_CLIENT_ID or WEB_RENDER_URL missing/undefined in env config, making the URLSearchParams/URL build fail or produce a client_id=undefined URL; the redisService.setKey call for youtube:state:<userId>:<state> throws (Redis down); an invalid mail/userId argument.

Common situations: Deploying without the GOOGLE_CONFIG nested env block configured; Redis connection failure; wrong env file loaded in the electron server; typos in config keys so ConfigService.get returns undefined.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/4437f3384105d40b. Report an issue: GitHub.