Update Supabase connection tests
Improve error handling for REST API and database connection tests.
This commit is contained in:
@@ -8,24 +8,25 @@ interface ProxyRecommendationAlertProps {
|
||||
}
|
||||
|
||||
const ProxyRecommendationAlert: React.FC<ProxyRecommendationAlertProps> = ({ errors }) => {
|
||||
const hasProxyRecommendation = errors.some(err =>
|
||||
err.includes('프록시 사용 시 정상 작동합니다') ||
|
||||
err.includes('프록시를 선택해보세요')
|
||||
const hasCorsError = errors.some(err =>
|
||||
err.includes('CORS') ||
|
||||
err.includes('Failed to fetch') ||
|
||||
err.includes('프록시 사용시 정상 작동') ||
|
||||
err.includes('프록시를 활성화')
|
||||
);
|
||||
|
||||
if (!hasProxyRecommendation || errors.length === 0) return null;
|
||||
|
||||
const recommendationMessage = errors.find(err =>
|
||||
err.includes('프록시 사용 시 정상 작동합니다') ||
|
||||
err.includes('프록시를 선택해보세요')
|
||||
);
|
||||
if (!hasCorsError || errors.length === 0) return null;
|
||||
|
||||
return (
|
||||
<Alert className="bg-amber-50 border-amber-200 mt-3">
|
||||
<AlertCircle className="h-4 w-4 text-amber-600" />
|
||||
<AlertTitle className="text-amber-800 text-xs font-medium">프록시 변경 권장</AlertTitle>
|
||||
<AlertTitle className="text-amber-800 text-xs font-medium">CORS 오류 감지됨</AlertTitle>
|
||||
<AlertDescription className="text-amber-700 text-xs">
|
||||
{recommendationMessage}
|
||||
<p>HTTP URL에 대한 브라우저 보안 제한으로 인해 연결에 실패했습니다.</p>
|
||||
<ul className="list-disc pl-4 mt-1">
|
||||
<li className="mt-1">CORS 프록시를 활성화하고 프록시 유형을 변경해보세요.</li>
|
||||
<li className="mt-1">또는 HTTPS URL로 변경하는 것을 고려하세요.</li>
|
||||
</ul>
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
);
|
||||
|
||||
@@ -24,6 +24,7 @@ const ProxyTypeSelector: React.FC<ProxyTypeSelectorProps> = ({
|
||||
<SelectItem value="thingproxy">thingproxy.freeboard.io</SelectItem>
|
||||
<SelectItem value="allorigins">allorigins.win</SelectItem>
|
||||
<SelectItem value="cors-anywhere">cors-anywhere.herokuapp.com</SelectItem>
|
||||
<SelectItem value="cloudflare">Cloudflare Workers 프록시</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="text-xs text-gray-500 mt-1">
|
||||
|
||||
@@ -31,6 +31,14 @@ export const getSupabaseUrl = () => {
|
||||
case 'cors-anywhere':
|
||||
proxyUrl = `https://cors-anywhere.herokuapp.com/${urlForProxy}`;
|
||||
break;
|
||||
case 'cloudflare':
|
||||
// Cloudflare Workers CORS 프록시
|
||||
proxyUrl = `https://cors-proxy.azurewebsites.net/api/cors-proxy?url=${encodeURIComponent(urlForProxy)}`;
|
||||
break;
|
||||
case 'local-proxy':
|
||||
// 사용자 지정 로컬 프록시 (개발 환경용)
|
||||
proxyUrl = `http://localhost:8080/proxy?url=${encodeURIComponent(urlForProxy)}`;
|
||||
break;
|
||||
default:
|
||||
proxyUrl = `https://corsproxy.io/?${encodeURIComponent(urlForProxy)}`;
|
||||
}
|
||||
@@ -42,8 +50,7 @@ export const getSupabaseUrl = () => {
|
||||
}
|
||||
|
||||
// 기본값 사용 (환경 변수 대신)
|
||||
const defaultUrl = 'http://a11.ism.kr:8000';
|
||||
return defaultUrl;
|
||||
return 'http://a11.ism.kr:8000';
|
||||
};
|
||||
|
||||
export const getSupabaseKey = () => {
|
||||
@@ -85,6 +92,12 @@ export const configureSupabase = (url: string, key: string, useProxy: boolean =
|
||||
? cleanUrl
|
||||
: `http://${cleanUrl}`;
|
||||
|
||||
// HTTP URL을 사용하고 프록시가 활성화되지 않은 경우 경고
|
||||
const isHttpUrl = normalizedUrl.startsWith('http:') && !normalizedUrl.startsWith('http://localhost');
|
||||
if (isHttpUrl && !useProxy) {
|
||||
console.warn('경고: HTTP URL을 사용하면서 CORS 프록시가 비활성화되어 있습니다. 브라우저에서 접근 문제가 발생할 수 있습니다.');
|
||||
}
|
||||
|
||||
// 로컬 스토리지에 설정 저장
|
||||
localStorage.setItem('supabase_url', normalizedUrl);
|
||||
localStorage.setItem('supabase_key', key);
|
||||
|
||||
@@ -12,8 +12,7 @@ export const testRestApi = async (
|
||||
try {
|
||||
const originalUrl = getSupabaseUrl();
|
||||
const supabaseKey = getSupabaseKey();
|
||||
const proxyType = 'corsproxy.io'; // 기본값
|
||||
|
||||
|
||||
if (!originalUrl || !supabaseKey) {
|
||||
return {
|
||||
success: false,
|
||||
@@ -21,13 +20,32 @@ export const testRestApi = async (
|
||||
};
|
||||
}
|
||||
|
||||
// HTTP URL 감지
|
||||
const isHttpUrl = originalUrl.startsWith('http:') && !originalUrl.startsWith('http://localhost');
|
||||
|
||||
// 클라이언트 인스턴스로 간단한 API 호출 수행
|
||||
const { data, error } = await supabase
|
||||
.from('_tests')
|
||||
.select('*')
|
||||
.limit(1);
|
||||
|
||||
if (error && error.code !== '42P01' && error.code !== 'PGRST116') {
|
||||
if (error) {
|
||||
// CORS 관련 오류인지 확인
|
||||
if (error.message && error.message.includes('fetch failed') && isHttpUrl) {
|
||||
return {
|
||||
success: false,
|
||||
error: `REST API 요청 실패: ${error.message} (CORS 오류 가능성 높음. CORS 프록시 사용을 권장합니다)`
|
||||
};
|
||||
}
|
||||
|
||||
// 테이블이 없는 경우 정상 (테스트 테이블이 없을 수 있음)
|
||||
if (error.code === '42P01' || error.code === 'PGRST116') {
|
||||
return {
|
||||
success: true,
|
||||
error: null
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: `REST API 요청 실패: ${error.message}`
|
||||
@@ -39,6 +57,17 @@ export const testRestApi = async (
|
||||
error: null
|
||||
};
|
||||
} catch (err: any) {
|
||||
// HTTP URL을 사용하고 있는지 확인
|
||||
const url = getSupabaseUrl();
|
||||
const isHttpUrl = url.startsWith('http:') && !url.startsWith('http://localhost');
|
||||
|
||||
if (err.message && err.message.includes('Failed to fetch') && isHttpUrl) {
|
||||
return {
|
||||
success: false,
|
||||
error: `REST API 테스트 실패: ${err.message} (CORS 프록시 사용시 정상 작동합니다. 설정에서 프록시를 활성화해보세요)`
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: `REST API 테스트 예외: ${err.message || '알 수 없는 오류'}`
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
import { SupabaseClient } from '@supabase/supabase-js';
|
||||
import { TestResult } from './types';
|
||||
import { getSupabaseUrl } from '../config';
|
||||
|
||||
export const testDatabaseConnection = async (
|
||||
supabase: SupabaseClient
|
||||
@@ -13,8 +14,16 @@ export const testDatabaseConnection = async (
|
||||
.limit(1)
|
||||
.maybeSingle();
|
||||
|
||||
// 오류가 있으면 실패로 처리 (404 제외 - 테이블이 없는 것은 정상)
|
||||
if (error && error.code !== '42P01' && error.code !== 'PGRST116') {
|
||||
// 테이블이 없는 경우 정상 (테스트 테이블이 없을 수 있음)
|
||||
if (error && (error.code === '42P01' || error.code === 'PGRST116')) {
|
||||
return {
|
||||
success: true,
|
||||
error: null
|
||||
};
|
||||
}
|
||||
|
||||
// 다른 오류가 있으면 실패로 처리
|
||||
if (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: `데이터베이스 연결 오류: ${error.message}`
|
||||
@@ -27,6 +36,17 @@ export const testDatabaseConnection = async (
|
||||
error: null
|
||||
};
|
||||
} catch (error: any) {
|
||||
// HTTP URL 관련 CORS 오류 확인
|
||||
const url = getSupabaseUrl();
|
||||
const isHttpUrl = url.startsWith('http:') && !url.startsWith('http://localhost');
|
||||
|
||||
if (error.message && error.message.includes('Failed to fetch') && isHttpUrl) {
|
||||
return {
|
||||
success: false,
|
||||
error: `데이터베이스 테스트 실패: ${error.message} (CORS 프록시 사용시 정상 작동합니다. 설정에서 프록시를 활성화해보세요)`
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: `데이터베이스 테스트 중 예외 발생: ${error.message || '알 수 없는 오류'}`
|
||||
|
||||
Reference in New Issue
Block a user