DIYgod/RSSHub · error · Error
Cannot get link
Error message
Cannot get link
What it means
Inside parseListLinkDateItem the code reads element.find('a').attr('href'); if the anchor has no href attribute the scraper cannot build a link and aborts. It indicates the rsgis.whu.edu.cn list HTML no longer matches the expected <li><a href=...> shape.
Source
Thrown at lib/routes/whu/rsgis.ts:112
* @returns Whether or not weixin post
*/
function checkExternal(link: string): boolean {
const matchWeixin = link.match(/^((http:\/\/)|(https:\/\/))?([\dA-Za-z]([\dA-Za-z-]{0,61}[\dA-Za-z])?\.)+[A-Za-z]{2,6}(\/)/);
return !!matchWeixin?.length;
}
/**
* Get information from a list of paired link and date.
*
* @param element
* @returns A list of RSS meta node.
*/
function parseListLinkDateItem(element: Cheerio<Element>, currentUrl: string) {
const linkElement = element.find('a');
const title = linkElement.text();
const href = linkElement.attr('href');
if (href === undefined) {
throw new Error('Cannot get link');
}
const external = checkExternal(href);
const link = external ? href : new URL(href, currentUrl).href;
const pubDate = element.find('div.date1').text();
return {
title,
link,
pubDate: timezone(parseDate(pubDate, 'YYYY-MM-DD'), 8),
description: title,
external,
};
}
async function getDetail(item: Post): Promise<DataItem | any> {
const link = item.link;
return link
? await cache.tryGet(`whu:rsgis:${link}`, async () => {
if (item.external) {View on GitHub (pinned to bed535e087)
Solutions
- Open rsgis.whu.edu.cn and confirm the list markup still uses <a href> inside the queried <li> containers; update the selector if the structure changed.
- Filter out items where find('a').attr('href') is undefined before calling parseListLinkDateItem rather than throwing.
- Report the page to the route maintainer (HPDell) with the offending URL.
Example fix
// defensive skip instead of throw
const href = linkElement.attr('href');
if (href === undefined) {
return null; // filtered out by a subsequent .filter(Boolean)
} Defensive patterns
Strategy: validation
Validate before calling
// Inside parseListLinkDateItem, skip link-less rows instead of throwing
const linkElement = element.find('a');
const href = linkElement.attr('href');
if (href === undefined) return null; // caller filters nulls Type guard
function hasHref(el: Cheerio<Element>): boolean {
return el.attr('href') !== undefined;
} Try / catch
const posts = list.toArray()
.map((item) => {
try { return parseListLinkDateItem($(item), baseUrl); }
catch { return null; }
})
.filter((x): x is Post => x !== null); Prevention
- Treat scraped HTML as untrusted — never throw on a missing optional attribute; skip the row.
- Add structure assertions in tests against a saved fixture of the live page.
- Log when skip rates climb so a silent site redesign is detected early.
When it happens
Trigger: Any of the list selectors in handleIndex/handlePostList yields an <li> whose <a> lacks href — e.g. a placeholder item, a date-only row, or a site redesign that dropped/renamed the anchor.
Common situations: The school site template changed; a list item is a non-link divider/header; HTML was partially loaded due to network truncation.
Related errors
- Could not locate initials script on page
- Cannot extract __INITIAL_SSR_STATE__
- 无法找到 Body.js 脚本文件
- this route is empty, please check the original site or <a hr
- Unknown type: ${item.type}
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/fa3b9933031e8fd9.
Report an issue: GitHub.