/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ export function fetchFailureDetail(error) { const parts = [String(error?.message || 'fetch failed')] const cause = error?.cause if (cause) { const fields = [ cause.code ? `code=${cause.code}` : '', cause.syscall ? `syscall=${cause.syscall}` : '', cause.address ? `address=${cause.address}` : '', cause.port ? `port=${cause.port}` : '' ].filter(Boolean) if (cause.message && !parts.includes(cause.message)) { parts.push(cause.message) } if (fields.length) { parts.push(fields.join(' ')) } } return parts.join('; ') } export function isLocalhostPermissionError(error) { const detail = fetchFailureDetail(error) return detail.includes('EPERM') || detail.includes('EACCES') } export function localNetworkHint(error, command) { if (isLocalhostPermissionError(error)) { return ` If this is a sandbox localhost permission blocker, rerun this command with localhost/127.0.0.1 access: ${command}. Do not switch to Codex in-app Browser (iab).` } return ` If this environment blocks localhost, run ${command} from the repo root or set MODERN_UI_BASE_URL to a reachable /modern/app/ endpoint; do not switch to Codex in-app Browser (iab).` }