fix: Resolve Quick Start Wizard error display and policy creation issues
- Fixed error response format to send error message as string instead of boolean - Enhanced error handling in QuickStartWizard to use handleApiError helper - Improved policy creation with temp directory verification - Added specific error detection for policy operations - Fixed error display showing "true" instead of actual error message - Ensured temp directory exists before writing policy files - Added file access verification before executing MinIO commands - Better cleanup of temporary files on failure 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -57,7 +57,7 @@ const errorHandler = (err, req, res, next) => {
|
|||||||
const message = error.message || 'Internal Server Error';
|
const message = error.message || 'Internal Server Error';
|
||||||
|
|
||||||
res.status(statusCode).json({
|
res.status(statusCode).json({
|
||||||
error: true,
|
error: message,
|
||||||
message,
|
message,
|
||||||
...(config.app.env === 'development' && { stack: err.stack }),
|
...(config.app.env === 'development' && { stack: err.stack }),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -100,6 +100,12 @@ class MinIOService {
|
|||||||
if (error.stderr.includes('Access Denied')) {
|
if (error.stderr.includes('Access Denied')) {
|
||||||
throw new AppError('Access denied', 403);
|
throw new AppError('Access denied', 403);
|
||||||
}
|
}
|
||||||
|
if (error.stderr.includes('already exists')) {
|
||||||
|
throw new AppError('Resource already exists', 409);
|
||||||
|
}
|
||||||
|
if (error.stderr.includes('policy')) {
|
||||||
|
throw new AppError(`Policy operation failed: ${error.stderr}`, 400);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new AppError(error.message || 'Command execution failed', 500);
|
throw new AppError(error.message || 'Command execution failed', 500);
|
||||||
@@ -232,9 +238,15 @@ class MinIOService {
|
|||||||
|
|
||||||
// Write policy to temp file
|
// Write policy to temp file
|
||||||
const policyFile = path.join(this.tempDir, `${policyName}-${Date.now()}.json`);
|
const policyFile = path.join(this.tempDir, `${policyName}-${Date.now()}.json`);
|
||||||
|
|
||||||
|
// Ensure temp directory exists before writing
|
||||||
|
await fs.mkdir(this.tempDir, { recursive: true });
|
||||||
await fs.writeFile(policyFile, JSON.stringify(policy, null, 2));
|
await fs.writeFile(policyFile, JSON.stringify(policy, null, 2));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Verify the file was written
|
||||||
|
await fs.access(policyFile);
|
||||||
|
|
||||||
// Create and attach policy
|
// Create and attach policy
|
||||||
await this.executeCommand(
|
await this.executeCommand(
|
||||||
`mc admin policy create ${this.alias} ${policyName} ${policyFile}`
|
`mc admin policy create ${this.alias} ${policyName} ${policyFile}`
|
||||||
@@ -328,16 +340,27 @@ class MinIOService {
|
|||||||
const policyFile = path.join(this.tempDir, `${policyName}-${Date.now()}.json`);
|
const policyFile = path.join(this.tempDir, `${policyName}-${Date.now()}.json`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Ensure temp directory exists before writing
|
||||||
|
await fs.mkdir(this.tempDir, { recursive: true });
|
||||||
|
|
||||||
await fs.writeFile(policyFile,
|
await fs.writeFile(policyFile,
|
||||||
typeof policyDocument === 'string' ? policyDocument : JSON.stringify(policyDocument, null, 2)
|
typeof policyDocument === 'string' ? policyDocument : JSON.stringify(policyDocument, null, 2)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Verify the file was written
|
||||||
|
await fs.access(policyFile);
|
||||||
|
|
||||||
await this.executeCommand(
|
await this.executeCommand(
|
||||||
`mc admin policy create ${this.alias} ${policyName} ${policyFile}`
|
`mc admin policy create ${this.alias} ${policyName} ${policyFile}`
|
||||||
);
|
);
|
||||||
|
|
||||||
return { message: 'Policy created successfully', policyName };
|
return { message: 'Policy created successfully', policyName };
|
||||||
|
} catch (error) {
|
||||||
|
// Clean up file if it exists
|
||||||
|
await fs.unlink(policyFile).catch(() => {});
|
||||||
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
|
// Always try to clean up the temp file
|
||||||
await fs.unlink(policyFile).catch(() => {});
|
await fs.unlink(policyFile).catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import {
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import userService from '../../services/userService';
|
import userService from '../../services/userService';
|
||||||
import policyService from '../../services/policyService';
|
import policyService from '../../services/policyService';
|
||||||
import api from '../../services/api';
|
import api, { handleApiError } from '../../services/api';
|
||||||
|
|
||||||
interface QuickStartWizardProps {
|
interface QuickStartWizardProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -219,8 +219,9 @@ const QuickStartWizard: React.FC<QuickStartWizardProps> = ({
|
|||||||
|
|
||||||
setCompletedSetup(results);
|
setCompletedSetup(results);
|
||||||
setActiveStep(steps.length);
|
setActiveStep(steps.length);
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
setError(err instanceof Error ? err.message : t('quickWizard:errors.creationFailed'));
|
const errorMessage = handleApiError(err);
|
||||||
|
setError(errorMessage);
|
||||||
setIsCreating(false);
|
setIsCreating(false);
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -297,7 +298,7 @@ const QuickStartWizard: React.FC<QuickStartWizardProps> = ({
|
|||||||
value={setupData.userPassword}
|
value={setupData.userPassword}
|
||||||
onChange={(e) => setSetupData({ ...setupData, userPassword: e.target.value })}
|
onChange={(e) => setSetupData({ ...setupData, userPassword: e.target.value })}
|
||||||
error={!!error && activeStep === 1}
|
error={!!error && activeStep === 1}
|
||||||
helperText={error || t('quickWizard:user.passwordHelper')}
|
helperText={(error && activeStep === 1 ? error : '') || t('quickWizard:user.passwordHelper')}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
endAdornment: (
|
endAdornment: (
|
||||||
<InputAdornment position="end">
|
<InputAdornment position="end">
|
||||||
|
|||||||
Reference in New Issue
Block a user