-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
effect-tsEffect-TS patterns and usageEffect-TS patterns and usagepkg:cliIssues related to @effect-migrate/cli packageIssues related to @effect-migrate/cli packagepriority:lowLow priorityLow prioritytype:featureNew feature or requestNew feature or request
Description
Summary
Add timeout protection to dynamic preset imports in loadPreset to prevent the CLI from hanging indefinitely when a preset package has issues during module initialization.
Problem
Current implementation in packages/cli/src/loaders/presets.ts:
const module = yield* Effect.tryPromise({
try: () => import(name),
catch: error => new PresetLoadError({
preset: name,
message: `Failed to import: ${String(error)}`
})
})Edge case: If a preset package:
- Has an infinite loop during initialization
- Makes a hanging network request
- Deadlocks on a resource
...the CLI will hang indefinitely with no feedback to the user.
Proposed Solution
Wrap the import with Effect.timeout:
const loadPreset = (name: string): Effect.Effect<Preset, PresetLoadError> =>
Effect.gen(function* () {
// Dynamically import preset module with timeout
const module = yield* Effect.tryPromise({
try: () => import(name),
catch: error =>
new PresetLoadError({
preset: name,
message: `Failed to import: ${String(error)}`
})
}).pipe(
Effect.timeout("5 seconds"), // Reasonable timeout for module loading
Effect.catchTag("TimeoutException", () =>
Effect.fail(
new PresetLoadError({
preset: name,
message: "Import timed out after 5 seconds (possible infinite loop or deadlock)"
})
)
)
)
// ... rest of validation
})Configuration
Consider making timeout configurable:
// In config schema
presets: {
names: ReadonlyArray<string>
timeout?: number // milliseconds, default 5000
}Benefits
- Prevents CLI from hanging indefinitely
- Provides clear error message to user
- Allows graceful fallback (warning + continue)
- Protects against malicious or buggy preset packages
Acceptance Criteria
-
Effect.timeoutadded to preset imports - Timeout exception caught and converted to
PresetLoadError - Default timeout of 5 seconds
- Error message explains timeout occurred
- Test added for timeout scenario (mock slow import)
- Documentation updated
Testing
it.effect("should timeout on slow preset import", () =>
Effect.gen(function* () {
// Mock preset that takes 10 seconds to load
const slowPreset = {
rules: [],
defaults: {}
}
// Should fail with timeout error
const result = yield* Effect.flip(loadPreset("slow-preset"))
expect(result).toBeInstanceOf(PresetLoadError)
expect(result.message).toContain("timed out")
})
)Related
- Uses Effect.timeout from
effect/Effect - Complements existing error handling in
loadPresets - Thread: https://ampcode.com/threads/T-09db5199-2c22-42fd-9730-3a6f1c42e570
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
effect-tsEffect-TS patterns and usageEffect-TS patterns and usagepkg:cliIssues related to @effect-migrate/cli packageIssues related to @effect-migrate/cli packagepriority:lowLow priorityLow prioritytype:featureNew feature or requestNew feature or request