Skip to content

Commit

Permalink
Refactor error handling + workaround for output handler bug
Browse files Browse the repository at this point in the history
  • Loading branch information
vapidinfinity committed Jul 7, 2024
1 parent b54821d commit 52c1174
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 16 deletions.
4 changes: 2 additions & 2 deletions Mythic.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2815;
CURRENT_PROJECT_VERSION = 2827;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "\"Mythic/Preview Content\"";
DEVELOPMENT_TEAM = "";
Expand Down Expand Up @@ -764,7 +764,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2815;
CURRENT_PROJECT_VERSION = 2827;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "\"Mythic/Preview Content\"";
DEVELOPMENT_TEAM = "";
Expand Down
3 changes: 3 additions & 0 deletions Mythic/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -47795,6 +47795,9 @@
}
}
}
},
"Unable to proceed with installation." : {

},
"Unable to uninstall \"%@\"." : {
"localizations" : {
Expand Down
26 changes: 12 additions & 14 deletions Mythic/Utilities/Legendary/LegendaryInterface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ final class Legendary {

task.qualityOfService = .userInitiated

let output: CommandOutput = .init()
let output: CommandOutput = .init() // weakly captured output tends to deallocate prematurely

stderr.fileHandleForReading.readabilityHandler = { [weak stdin, weak output] handle in
let availableOutput = String(decoding: handle.availableData, as: UTF8.self)
Expand All @@ -111,7 +111,7 @@ final class Legendary {
stdin.fileHandleForWriting.write(data)
}
output.stderr = availableOutput
completion(output) // ⚠️ FIXME: critical performance issues
completion(output)
}

stdout.fileHandleForReading.readabilityHandler = { [weak stdin, weak output] handle in
Expand All @@ -123,7 +123,7 @@ final class Legendary {
stdin.fileHandleForWriting.write(data)
}
output.stdout = availableOutput
completion(output) // ⚠️ FIXME: critical performance issues
completion(output)
}

task.terminationHandler = { _ in
Expand Down Expand Up @@ -250,22 +250,20 @@ final class Legendary {
var error: Error?

try await command(arguments: argBuilder, identifier: "install") { output in
if output.stdout.contains("Installation requirements check returned the following results:") {
output.stdout.enumerateLines { line, _ in
if let match = try? Regex(#"Failure: (.*)"#).firstMatch(in: output.stdout) {
stopCommand(identifier: "install")
error = InstallationError(errorDescription: .init(match.last?.substring ?? "Unknown Error"))
return
}
}
} else if let match = try? Regex(#"(ERROR|CRITICAL): (.*)"#).firstMatch(in: output.stderr) {
guard !output.stdout.contains("All done! Download manager quitting...") else {
operation.current = nil; return
}

if let match = try? Regex(#"Failure: (.*)"#).firstMatch(in: output.stdout) {
stopCommand(identifier: "install")
error = InstallationError(errorDescription: .init(match.last?.substring ?? "Unknown Error"))
return
}

guard !output.stdout.contains("All done! Download manager quitting...") else {
operation.current = nil; return
if let match = try? Regex(#"(ERROR|CRITICAL): (.*)"#).firstMatch(in: output.stderr) {
stopCommand(identifier: "install")
error = InstallationError(errorDescription: .init(match.last?.substring ?? "Unknown Error"))
return
}

if let match = try? progressRegex.firstMatch(in: output.stderr) {
Expand Down
24 changes: 24 additions & 0 deletions Mythic/Views/Unified/Sheets/InstallGameView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ struct InstallViewEvo: View {
@State private var supportedPlatforms: [GamePlatform]?
@State var platform: GamePlatform = .macOS

@State private var isInstallationErrorPresented: Bool = false
@State private var installationError: Error?

@AppStorage("installBaseURL") private var baseURL: URL = Bundle.appGames!
@ObservedObject var operation: GameOperation = .shared

Expand All @@ -31,12 +34,25 @@ struct InstallViewEvo: View {
fetchingOptionalPacks = true

try? await Legendary.command(arguments: ["install", game.id], identifier: "parseOptionalPacks") { output in

if output.stdout.contains("Installation requirements check returned the following results:") {
if let match = try? Regex(#"Failure: (.*)"#).firstMatch(in: output.stdout) {
Legendary.stopCommand(identifier: "install")
installationError = Legendary.InstallationError(errorDescription: .init(match.last?.substring ?? "Unknown Error"))
isInstallationErrorPresented = true
return
}
}

if output.stdout.contains("Do you wish to install") || output.stdout.contains("Additional packs") {
Legendary.runningCommands["parseOptionalPacks"]?.terminate(); return
}

print("\noptipacks stdout interation \(output.stdout)\n")
if output.stdout.contains("The following optional packs are available") { // hate hardcoding
print("optipacks found")
output.stdout.enumerateLines { line, _ in
print("optipack enum \(line)")
if let match = try? Regex(#"\s*\* (?<identifier>\w+) - (?<name>.+)"#).firstMatch(in: line) {
optionalPacks.updateValue(String(match["name"]?.substring ?? .init()), forKey: String(match["identifier"]?.substring ?? .init()))
}
Expand All @@ -52,6 +68,13 @@ struct InstallViewEvo: View {

fetchingOptionalPacks = false
}
.alert(isPresented: $isInstallationErrorPresented) {
Alert(
title: .init("Unable to proceed with installation."),
message: .init(installationError?.localizedDescription ?? "Unknown error."),
dismissButton: .default(Text("OK"))
)
}

if operation.current != nil {
Text("Cannot fetch selected downloads while other items are downloading.")
Expand Down Expand Up @@ -200,6 +223,7 @@ struct InstallViewEvo: View {
}
.disabled(fetchingOptionalPacks)
.buttonStyle(.borderedProminent)
.disabled(installationError != nil)
}
}
}
Expand Down

0 comments on commit 52c1174

Please sign in to comment.