maotoumao/MusicFree · warning

无法打开链接

Error message

无法打开链接

What it means

The openUrl utility wraps React Native's `Linking.canOpenURL`/`Linking.openURL`. When either call rejects — most commonly because no installed app can handle the URL scheme, or iOS hasn't whitelisted the scheme in LSApplicationQueriesSchemes — the catch block shows the toast "无法打开链接" (cannot open link). It indicates the OS refused or was unable to handle the link request.

Source

Thrown at src/utils/openUrl.ts:9

import { Linking } from "react-native";
import Toast from "./toast";

export default async function (url: string) {
    try {
        await Linking.canOpenURL(url);
        return Linking.openURL(url);
    } catch {
        Toast.warn("无法打开链接");
    }
}

View on GitHub (pinned to d118b18b3d)

Solutions

  1. Verify the URL scheme is one the device can handle (browser http/https links are safest) and that the URL is well-formed and properly encoded.
  2. On iOS, add every custom scheme you query to LSApplicationQueriesSchemes in Info.plist.
  3. On Android, ensure the URL has a valid https/http scheme or that an app exists that registers the custom scheme.
  4. Handle the rejection yourself with a fallback: copy the URL to clipboard or open it inside an in-app WebView instead of relying on the OS.
  5. Log the failing URL in the catch block to identify which link is broken.

Example fix

// before
export default async function (url: string) {
    try {
        await Linking.canOpenURL(url);
        return Linking.openURL(url);
    } catch {
        Toast.warn("无法打开链接");
    }
}

// after
export default async function (url: string) {
    try {
        const supported = await Linking.canOpenURL(url);
        if (!supported) throw new Error(`unsupported: ${url}`);
        return Linking.openURL(url);
    } catch (e) {
        console.warn('openUrl failed', url, e);
        Toast.warn("无法打开链接");
        Clipboard.setString(url);
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

import { Linking } from 'react-native';

export async function canOpen(url: string) {
    try {
        if (!/^https?:\/\//.test(url)) return false;
        return await Linking.canOpenURL(url);
    } catch {
        return false;
    }
}

if (await canOpen(url)) {
    openUrl(url);
} else {
    Toast.warn('无法打开链接');
}

Type guard

function isHttpUrl(url: string): boolean {
    try {
        const u = new URL(url);
        return u.protocol === 'http:' || u.protocol === 'https:';
    } catch {
        return false;
    }
}

Try / catch

try {
    const supported = await Linking.canOpenURL(url);
    if (!supported) throw new Error(`no handler for ${url}`);
    await Linking.openURL(url);
} catch (e) {
    console.warn('openUrl failed', url, e);
    Toast.warn('无法打开链接');
    Clipboard.setString(url); // fallback so the user can still reach it
}

Prevention

When it happens

Trigger: Calling openUrl() with a URL whose scheme no app registers (e.g. a custom scheme when the target app isn't installed); on iOS, a scheme not declared in LSApplicationQueriesSchemes so canOpenURL throws; malformed URLs; or openURL failing due to missing intent handlers on Android.

Common situations: Tapping an external link in markdown content when no browser or matching app is installed; iOS 9+ scheme-query restriction after adding new deeplinks; URL built with unencoded characters; testing on a fresh emulator with no browser app.

Related errors


AI-assisted analysis of maotoumao/MusicFree@d118b18b3d (2026-08-30). Data as JSON: /api/errors/ca57f397c092224a. Report an issue: GitHub.