mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
feat: add frontend features store and FEATURE_NOT_INSTALLED error handling
Add Zustand features store for tracking AI feature bundle state with fetch, refresh, isToolInstalled, and getBundleForTool methods. Extend parseApiError to return structured FeatureNotInstalledError objects when the backend returns FEATURE_NOT_INSTALLED, and handle them in both tool and pipeline processor hooks with user-friendly messages.
This commit is contained in:
@@ -145,7 +145,14 @@ export function usePipelineProcessor() {
|
||||
} else {
|
||||
try {
|
||||
const body = JSON.parse(xhr.responseText);
|
||||
setError(parseApiError(body, xhr.status));
|
||||
const parsed = parseApiError(body, xhr.status);
|
||||
if (typeof parsed === "object" && parsed.type === "feature_not_installed") {
|
||||
setError(
|
||||
`Feature "${parsed.featureName}" is not installed. Enable it in Settings → AI Features.`,
|
||||
);
|
||||
} else {
|
||||
setError(parsed as string);
|
||||
}
|
||||
} catch {
|
||||
setError(`Processing failed: ${xhr.status}`);
|
||||
}
|
||||
@@ -270,7 +277,12 @@ export function usePipelineProcessor() {
|
||||
errorMsg += ` (${body.errors.length} files failed)`;
|
||||
}
|
||||
} else {
|
||||
errorMsg = parseApiError(body, response.status);
|
||||
const parsed = parseApiError(body, response.status);
|
||||
if (typeof parsed === "object" && parsed.type === "feature_not_installed") {
|
||||
errorMsg = `Feature "${parsed.featureName}" is not installed. Enable it in Settings → AI Features.`;
|
||||
} else {
|
||||
errorMsg = parsed as string;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
errorMsg = `Batch processing failed: ${response.status}`;
|
||||
|
||||
@@ -233,7 +233,14 @@ export function useToolProcessor(toolId: string) {
|
||||
} else {
|
||||
try {
|
||||
const body = JSON.parse(xhr.responseText);
|
||||
setError(parseApiError(body, xhr.status));
|
||||
const parsed = parseApiError(body, xhr.status);
|
||||
if (typeof parsed === "object" && parsed.type === "feature_not_installed") {
|
||||
setError(
|
||||
`Feature "${parsed.featureName}" is not installed. Enable it in Settings → AI Features.`,
|
||||
);
|
||||
} else {
|
||||
setError(parsed as string);
|
||||
}
|
||||
} catch {
|
||||
setError(`Processing failed: ${xhr.status}`);
|
||||
}
|
||||
@@ -354,7 +361,12 @@ export function useToolProcessor(toolId: string) {
|
||||
let errorMsg: string;
|
||||
try {
|
||||
const body = JSON.parse(text);
|
||||
errorMsg = parseApiError(body, response.status);
|
||||
const parsed = parseApiError(body, response.status);
|
||||
if (typeof parsed === "object" && parsed.type === "feature_not_installed") {
|
||||
errorMsg = `Feature "${parsed.featureName}" is not installed. Enable it in Settings → AI Features.`;
|
||||
} else {
|
||||
errorMsg = parsed as string;
|
||||
}
|
||||
} catch {
|
||||
errorMsg = `Batch processing failed: ${response.status}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user