Skip to content

Commit

Permalink
Add error forcing mechanics
Browse files Browse the repository at this point in the history
  • Loading branch information
finestructure committed Dec 14, 2024
1 parent ecae5b9 commit befd5e1
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 3 deletions.
33 changes: 31 additions & 2 deletions Sources/App/Commands/Ingest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import Dependencies
import Fluent
import PostgresKit
import Vapor
Expand Down Expand Up @@ -168,13 +169,17 @@ func ingest(client: Client,
extension Ingestion {
static func ingest(client: Client, database: Database, package: Joined<Package, Repository>) async {
let result = await Result { () async throws(Ingestion.Error) -> Joined<Package, Repository> in
@Dependency(\.environment) var environment
Current.logger().info("Ingesting \(package.package.url)")

// Even though we have a `Joined<Package, Repository>` as a parameter, we must not rely
// on `repository` for owner/name as it will be nil when a package is first ingested.
// The only way to get `owner` and `repository` here is by parsing them from the URL.
let (owner, repository) = try await run {
try Github.parseOwnerName(url: package.model.url)
if environment.shouldFail(failureMode: .invalidURL) {
throw Github.Error.invalidURL(package.model.url)
}
return try Github.parseOwnerName(url: package.model.url)
} rethrowing: { _ in
Ingestion.Error.invalidURL(packageId: package.model.id!, url: package.model.url)
}
Expand Down Expand Up @@ -223,7 +228,12 @@ extension Ingestion {

static func findOrCreateRepository(on database: Database, for package: Joined<Package, Repository>) async throws(Ingestion.Error) -> Repository {
try await run {
try await Repository.findOrCreate(on: database, for: package.model)
@Dependency(\.environment) var environment
if environment.shouldFail(failureMode: .findOrCreateRepositoryFailed) {
throw Abort(.internalServerError)
}

return try await Repository.findOrCreate(on: database, for: package.model)
} rethrowing: {
Ingestion.Error(
packageId: package.model.id!,
Expand Down Expand Up @@ -251,6 +261,11 @@ extension Ingestion {


static func fetchMetadata(client: Client, package: Package, owner: String, repository: String) async throws(Github.Error) -> (Github.Metadata, Github.License?, Github.Readme?) {
@Dependency(\.environment) var environment
if environment.shouldFail(failureMode: .fetchMetadataFailed) {
throw Github.Error.requestFailed(.internalServerError)
}

async let metadata = try await Current.fetchMetadata(client, owner, repository)
async let license = await Current.fetchLicense(client, owner, repository)
async let readme = await Current.fetchReadme(client, owner, repository)
Expand Down Expand Up @@ -286,6 +301,20 @@ func updateRepository(on database: Database,
readmeInfo: Github.Readme?,
s3Readme: S3Readme?,
fork: Fork? = nil) async throws(Ingestion.Error.UnderlyingError) {
@Dependency(\.environment) var environment
if environment.shouldFail(failureMode: .noRepositoryMetadata) {
throw .noRepositoryMetadata(owner: repository.owner, name: repository.name)
}
if environment.shouldFail(failureMode: .repositorySaveFailed) {
throw .repositorySaveFailed(owner: repository.owner,
name: repository.name,
details: "TestError")
}
if environment.shouldFail(failureMode: .repositorySaveUniqueViolation) {
throw .repositorySaveUniqueViolation(owner: repository.owner,
name: repository.name,
details: "TestError")
}
guard let repoMetadata = metadata.repository else {
throw .noRepositoryMetadata(owner: repository.owner, name: repository.name)
}
Expand Down
19 changes: 18 additions & 1 deletion Sources/App/Core/Dependencies/EnvironmentClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ struct EnvironmentClient {
var mastodonCredentials: @Sendable () -> Mastodon.Credentials?
var mastodonPost: @Sendable (_ client: Client, _ post: String) async throws -> Void
var random: @Sendable (_ range: ClosedRange<Double>) -> Double = { XCTFail("random"); return Double.random(in: $0) }

enum FailureMode: String {
case fetchMetadataFailed
case findOrCreateRepositoryFailed
case invalidURL
case noRepositoryMetadata
case repositorySaveFailed
case repositorySaveUniqueViolation
}
var shouldFail: @Sendable (_ failureMode: FailureMode) -> Bool = { _ in false }
}


Expand Down Expand Up @@ -100,7 +110,14 @@ extension EnvironmentClient: DependencyKey {
.map(Mastodon.Credentials.init(accessToken:))
},
mastodonPost: { client, message in try await Mastodon.post(client: client, message: message) },
random: { range in Double.random(in: range) }
random: { range in Double.random(in: range) },
shouldFail: { failureMode in
let shouldFail = Environment.get("FAILURE_MODE")
.map { Data($0.utf8) }
.flatMap { try? JSONDecoder().decode([String: Double].self, from: $0) } ?? [:]
guard let rate = shouldFail[failureMode.rawValue] else { return false }
return Double.random(in: 0...1) <= rate
}
)
}
}
Expand Down

0 comments on commit befd5e1

Please sign in to comment.