{"record":{"id":"11ab821d68b9e65f","repo":"yikart/AiToEarn","slug":"invalidworklink-11ab82","errorCode":"InvalidWorkLink","errorMessage":"InvalidWorkLink","messagePattern":"InvalidWorkLink","errorType":"error_code","errorClass":"AppException","httpStatus":null,"severity":"warning","filePath":"project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/douyin/douyin-work.provider.ts","lineNumber":17,"sourceCode":"import type { ChannelWorkDataResult, WorkLinkInfoInput, WorkProvider } from '../platforms.interface'\nimport { Injectable, Logger } from '@nestjs/common'\nimport { PublishType } from '@yikart/aitoearn-server-shared'\nimport { AccountType, AppException, ResponseCode } from '@yikart/common'\nimport axios from 'axios'\nimport { buildDouyinVideoWorkLink } from './douyin.interface'\n\n@Injectable()\nexport class DouyinWorkProvider implements WorkProvider {\n  readonly requiresCredentialForLinkInfo = false\n  private readonly logger = new Logger(DouyinWorkProvider.name)\n\n  async getLinkInfo(input: WorkLinkInfoInput): Promise<ChannelWorkDataResult> {\n    const resolvedUrl = await this.normalizeLink(input.link)\n    const dataId = this.parseWorkId(resolvedUrl)\n    if (!dataId) {\n      throw new AppException(ResponseCode.InvalidWorkLink)\n    }\n\n    const url = this.buildWorkLink(dataId, resolvedUrl)\n    return {\n      snapshots: [],\n      work: {\n        id: dataId,\n        url,\n        mediaType: PublishType.VIDEO,\n      },\n      extra: {\n        dataId,\n        uniqueId: `${AccountType.Douyin}_${dataId}`,\n        type: PublishType.VIDEO,\n        videoType: 'short',\n        resolvedUrl: url,\n      },\n      rawResponse: { resolvedUrl },","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/douyin/douyin-work.provider.ts#L1-L35","documentation":"getLinkInfo parses a Douyin work (video) link and throws InvalidWorkLink when parseWorkId cannot extract a data/work ID from the normalized URL. It means the provided link is not a recognized Douyin work URL.","triggerScenarios":"Calling getLinkInfo with a URL whose normalized form doesn't match Douyin work-URL patterns (e.g. user profile page, short-share URL that normalizeLink couldn't resolve, or non-Douyin link).","commonSituations":"Users pasting share text instead of a URL, new Douyin share-link formats the parser doesn't recognize, shortened links requiring an HTTP resolution step that failed or was skipped, or private/deleted works whose pages no longer resolve to an ID.","solutions":["Verify the input is a direct Douyin work URL (video detail page containing the work ID)","Extend normalizeLink/parseWorkId regexes to handle the new share-link format seen in production","Ask the user to re-share via the app's 'copy link' so the URL contains the work ID"],"exampleFix":"// before\nconst dataId = this.parseWorkId(resolvedUrl)\nif (!dataId) {\n  throw new AppException(ResponseCode.InvalidWorkLink)\n}\n// after\nconst dataId = this.parseWorkId(resolvedUrl)\nif (!dataId) {\n  throw new AppException(ResponseCode.InvalidWorkLink, { url: resolvedUrl })\n}","handlingStrategy":"validation","validationCode":"const DOUYIN_WORK_URL = /douyin\\.com\\/(video|note)\\/(\\d+)/\nexport function extractWorkId(link: string): string | null {\n  const m = link.match(DOUYIN_WORK_URL) ?? link.match(/douyin\\.com.*[?&]modal_id=(\\d+)/)\n  return m ? m[1] : null\n}\nif (!extractWorkId(userLink)) {\n  return { ok: false, message: 'Please share a direct Douyin video link' }\n}","typeGuard":"function isDouyinWorkUrl(url: string): boolean {\n  return /douyin\\.com\\/(video|note)\\/\\d+/.test(url) || /modal_id=\\d+/.test(url)\n}","tryCatchPattern":"try {\n  const info = await workProvider.getLinkInfo({ link })\n} catch (e) {\n  if (e instanceof AppException && e.code === 'InvalidWorkLink') {\n    return { ok: false, userMessage: 'This does not look like a Douyin video link. Use share > copy link.' }\n  }\n  throw e\n}","preventionTips":["Validate links client-side with a regex before calling the API","Normalize share text (extract the URL from v.douyin.com short links) before parsing","Add regression tests for new Douyin share-link formats reported by users","Show users an example of an acceptable link when validation fails"],"tags":["douyin","url-parsing","validation","input"],"backgroundTag":"invalid-work-url","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}