Skip to content

Invalid environment values silently default to 'development' - should error instead #220

@leogdion

Description

@leogdion

The environment string parsing only checks for "production", defaulting everything else to "development". Invalid values like "prod", "staging", "test" silently become "development" with no warning or error.

Current Code

```swift
// MistDemoConfig.swift:110
let envString = reader.string(
key: "environment",
environmentKey: "CLOUDKIT_ENVIRONMENT",
default: "development"
) ?? "development"

self.environment = envString == "production" ? .production : .development
// ⚠️ "prod", "PRODUCTION", "staging", etc. all become .development silently
```

Problem Scenarios

```bash

Typo - user expects production, gets development

export CLOUDKIT_ENVIRONMENT="prod" # Silent fallback to development!

Case sensitivity - unexpected behavior

export CLOUDKIT_ENVIRONMENT="PRODUCTION" # Silent fallback to development!

Wrong value - no feedback

export CLOUDKIT_ENVIRONMENT="staging" # Silent fallback to development!
```

Recommended Solution

```swift
self.environment = try {
let normalized = envString.lowercased()
switch normalized {
case "production", "prod":
return .production
case "development", "dev":
return .development
default:
throw ConfigurationError.invalidEnvironment(
envString,
validValues: ["production", "prod", "development", "dev"]
)
}
}()
```

Benefits

  • Fail fast: Catch typos immediately at startup
  • Clear errors: User knows exactly what went wrong
  • Case insensitive: "Production" and "PRODUCTION" both work
  • Aliases: Support common abbreviations like "prod" and "dev"

Alternative Solution (warning instead of error)

```swift
let normalized = envString.lowercased()
switch normalized {
case "production", "prod":
self.environment = .production
case "development", "dev":
self.environment = .development
default:
logger.warning("Invalid environment '(envString)', defaulting to 'development'. Valid: production, development")
self.environment = .development
}
```

Error Type Update

```swift
enum ConfigurationError: LocalizedError {
case missingAPIToken
case invalidEnvironment(String, validValues: [String])

var errorDescription: String? {
switch self {
case .invalidEnvironment(let value, let valid):
return "Invalid environment '(value)'. Valid values: (valid.joined(separator: ", "))"
// ...
}
}
}
```

Files Affected

  • Examples/MistDemo/Sources/MistDemo/Configuration/MistDemoConfig.swift:108-110
  • Examples/MistDemo/Sources/MistDemo/Configuration/MistDemoConfig.swift:43-46 (error type)

Acceptance Criteria

  • Invalid environment values throw clear error (or log warning)
  • Case-insensitive matching ("Production" works)
  • Support common aliases ("prod", "dev")
  • Error message lists valid values
  • Test coverage for invalid environment values
  • Documentation updated with valid environment values

Test Cases

```swift
@test func testInvalidEnvironmentThrowsError() async throws {
#expect(throws: ConfigurationError.invalidEnvironment) {
MistDemoConfig(environment: "staging")
}
}

@test func testCaseInsensitiveEnvironment() async throws {
let config1 = MistDemoConfig(environment: "Production")
#expect(config1.environment == .production)

let config2 = MistDemoConfig(environment: "DEVELOPMENT")
#expect(config2.environment == .development)
}

@test func testEnvironmentAliases() async throws {
let prod = MistDemoConfig(environment: "prod")
#expect(prod.environment == .production)

let dev = MistDemoConfig(environment: "dev")
#expect(dev.environment == .development)
}
```

References

  • MistKit environment types: Sources/MistKit/Environment.swift

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority: highShould fix soonvalidationInput validation

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions