Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion webui/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@
api.logout();
console.error('Login error:', error);

if (error.message.includes('CORS blocked')) {
if (error.message.startsWith('Network error:')) {
showError(error.message);
} else if (error.message.includes('Failed to fetch') || error.message.includes('NetworkError')) {
showError('Unable to connect to the gateway. Please check the endpoint URL and ensure the server is running.');
Expand Down
15 changes: 9 additions & 6 deletions webui/web/js/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -717,9 +717,10 @@ class VersityAPI {
signal: signal || undefined,
});
} catch (e) {
// Browsers surface CORS blocks as a generic TypeError.
// Browsers surface network-level failures (CORS, TLS/certificate errors,
// unreachable host) as a generic TypeError with no further detail.
if (e instanceof TypeError) {
throw new Error(`CORS blocked by gateway. Allow origin ${window.location.origin} and headers Authorization, X-Amz-Date, X-Amz-Content-Sha256, Content-Type.`);
throw new Error(`Network error: cannot reach gateway. Common causes: CORS policy (gateway must allow origin ${window.location.origin}), TLS/certificate error (untrusted or self-signed certificate rejected by the browser), or the gateway is unreachable.`);
}
throw e;
}
Expand Down Expand Up @@ -788,9 +789,9 @@ class VersityAPI {
await this.listBucketsS3();
this.setAdminRole(false);
} catch (s3Error) {
// If the gateway is reachable but the browser blocks the response due to CORS,
// surface that as an error so the UI can show a useful message.
if (s3Error && typeof s3Error.message === 'string' && s3Error.message.includes('CORS blocked')) {
// If the request failed at the network level (CORS, TLS, or unreachable),
// surface that error so the UI can show a useful diagnostic message.
if (s3Error && typeof s3Error.message === 'string' && s3Error.message.startsWith('Network error:')) {
throw s3Error;
}
return 'none';
Expand Down Expand Up @@ -931,8 +932,10 @@ class VersityAPI {
try {
httpResponse = await fetch(presignedUrl, { method: 'GET' });
} catch (e) {
// Browsers surface network-level failures (CORS, TLS/certificate errors,
// unreachable host) as a generic TypeError with no further detail.
if (e instanceof TypeError) {
throw new Error(`CORS blocked by gateway. Allow origin ${window.location.origin} for S3 responses (GET / and bucket/object operations).`);
throw new Error(`Network error: cannot reach gateway. Common causes: CORS policy (gateway must allow origin ${window.location.origin}), TLS/certificate error (untrusted or self-signed certificate rejected by the browser), or the gateway is unreachable.`);
}
throw e;
}
Expand Down
Loading