JohnSundell/Marathon

Verbose prints the underlying error

Opened this issue · 1 comments

Errors are currently being masked.

@discardableResult internal func perform<T>(_ expression: @autoclosure () throws -> T, orThrow errorExpression: @autoclosure () -> Error) throws -> T {
    do {
        return try expression()
    } catch {
        throw errorExpression()
    }
}

As you're no doubt aware: The above code facilitates error erasure like so.

let file = try perform(FileSystem().createFile(at: path, contents: data), orThrow: Error.failedToCreateFile(path))

The message for this error will state "Failed to create script" but the underlying reason for the failure, is lost.

public var message: String {
    switch self {
    case .missingName:
        return "No script name given"
    case .failedToCreateFile(let name):
        return "Failed to create script file named '\(name)'"
    }
}

With Pull 40 we may be able to bubble up the underlying error at key areas like this that show only for the --verbose command.

Would you be interested in taking Marathon in that direction?

At the moment it looks like verbose is used exclusively for shell specific tasks.

@discardableResult internal func shellOut(to command: String,
                                          in folder: Folder = Folder.current,
                                          printer: Printer) throws -> String {
    do {
        printer.verboseOutput("$ cd \"\(folder.path)\" && \(command)")
        let output = try shellOut(to: command, at: folder.path)
        printer.verboseOutput(output)

        return output
    } catch {
        let error = (error as? ShellOutError).require()

        if !error.output.isEmpty {
            printer.verboseOutput(error.output)
        }

        printer.verboseOutput(error.message)

        throw error
    }
}