Update Supabase connection tests

Improve error handling for REST API and database connection tests.
This commit is contained in:
gpt-engineer-app[bot]
2025-03-15 12:55:36 +00:00
parent b30fb33384
commit 5fd4c183eb
5 changed files with 82 additions and 18 deletions

View File

@@ -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>
);

View File

@@ -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">

View File

@@ -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);

View File

@@ -12,7 +12,6 @@ export const testRestApi = async (
try {
const originalUrl = getSupabaseUrl();
const supabaseKey = getSupabaseKey();
const proxyType = 'corsproxy.io'; // 기본값
if (!originalUrl || !supabaseKey) {
return {
@@ -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 || '알 수 없는 오류'}`

View File

@@ -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 || '알 수 없는 오류'}`