mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-21 07:36:40 +00:00
fix(sso): surface config load, test, and removal errors in the SSO settings UI (#1265)
The SSO provider settings previously swallowed three failure paths: the provider-config load on mount, the connection test, and provider removal. A transient backend error, a tier-gate rejection, or a failed removal left the admin with no feedback at all. Each path now surfaces the backend message (or a clear fallback) through the standard error toast, matching the existing save handler. The connection-test handler also checks the response status before treating the body as a test result, so an API or authorization failure is no longer reported as a failed identity-provider connection. Adds component tests covering the non-ok and network-failure branches for each handler, including the unparseable-error-body fallback.
This commit is contained in:
@@ -105,15 +105,23 @@ function ProviderCard({ providerId, type, label, initialConfig, onSave }: {
|
||||
setTestResult(null);
|
||||
try {
|
||||
const res = await apiFetch(`/sso/config/${providerId}/test`, { method: 'POST' });
|
||||
const data = await res.json();
|
||||
const data = await res.json().catch(() => null);
|
||||
if (!res.ok) {
|
||||
const message = data?.error || data?.message || 'Connection test failed';
|
||||
setTestResult({ success: false, error: message });
|
||||
toast.error(message);
|
||||
return;
|
||||
}
|
||||
setTestResult(data);
|
||||
if (data.success) {
|
||||
if (data?.success) {
|
||||
toast.success('Connection successful');
|
||||
} else {
|
||||
toast.error(data.error || 'Connection failed');
|
||||
toast.error(data?.error || 'Connection failed');
|
||||
}
|
||||
} catch {
|
||||
setTestResult({ success: false, error: 'Connection test failed' });
|
||||
} catch (error: unknown) {
|
||||
const message = (error as Error)?.message || 'Connection test failed';
|
||||
setTestResult({ success: false, error: message });
|
||||
toast.error(message);
|
||||
} finally {
|
||||
setTesting(false);
|
||||
}
|
||||
@@ -127,9 +135,12 @@ function ProviderCard({ providerId, type, label, initialConfig, onSave }: {
|
||||
setConfig({ enabled: false });
|
||||
setExpanded(false);
|
||||
onSave();
|
||||
} else {
|
||||
const data = await res.json().catch(() => null);
|
||||
toast.error(data?.error || data?.message || 'Failed to remove provider');
|
||||
}
|
||||
} catch {
|
||||
toast.error('Failed to remove provider');
|
||||
} catch (error: unknown) {
|
||||
toast.error((error as Error)?.message || 'Failed to remove provider');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -408,8 +419,15 @@ export function SSOSection() {
|
||||
const fetchConfigs = async () => {
|
||||
try {
|
||||
const res = await apiFetch('/sso/config');
|
||||
if (res.ok) setConfigs(await res.json());
|
||||
} catch { /* ignore fetch errors */ }
|
||||
if (res.ok) {
|
||||
setConfigs(await res.json());
|
||||
} else {
|
||||
const data = await res.json().catch(() => null);
|
||||
toast.error(data?.error || data?.message || 'Failed to load SSO configuration');
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
toast.error((error as Error)?.message || 'Failed to load SSO configuration');
|
||||
}
|
||||
};
|
||||
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
|
||||
Reference in New Issue
Block a user