Skip to content

Commit

Permalink
Further improvements to error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Mar 30, 2019
1 parent 5e1140e commit 0edd750
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 17 deletions.
28 changes: 15 additions & 13 deletions Gifski/Gifski.swift
Expand Up @@ -5,9 +5,9 @@ final class Gifski {
enum Error: LocalizedError {
case invalidSettings
case generateFrameFailed(Swift.Error)
case addFrameFailed(GifskiWrapperError)
case endAddingFramesFailed(GifskiWrapperError)
case writeFailed(GifskiWrapperError)
case addFrameFailed(Swift.Error)
case endAddingFramesFailed(Swift.Error)
case writeFailed(Swift.Error)
case cancelled

var errorDescription: String? {
Expand Down Expand Up @@ -53,7 +53,14 @@ final class Gifski {
- Parameter completionHandler: Guaranteed to be called on the main thread
*/
static func run(_ conversion: Conversion, completionHandler: ((Error?) -> Void)?) {
let completionHandlerOnce = Once().wrap { error in
var progress = Progress(parent: .current())
progress.fileURL = conversion.output

let completionHandlerOnce = Once().wrap { (error: Error?) -> Void in
if error != nil {
progress.cancel()
}

DispatchQueue.main.async {
completionHandler?(error)
}
Expand All @@ -72,24 +79,19 @@ final class Gifski {
return
}

var progress = Progress(parent: .current())
progress.fileURL = conversion.output

gifski.setProgressCallback(context: &progress) { context in
let progress = context!.assumingMemoryBound(to: Progress.self).pointee
progress.completedUnitCount += 1
return progress.isCancelled ? 0 : 1
}

DispatchQueue.global(qos: .utility).async {
progress.publish()
defer { progress.unpublish() }

let asset = AVURLAsset(url: conversion.input, options: nil)
let generator = AVAssetImageGenerator(asset: asset)
generator.requestedTimeToleranceAfter = .zero
generator.requestedTimeToleranceBefore = .zero
generator.appliesPreferredTrackTransform = true

progress.cancellationHandler = {
generator.cancelAllCGImageGeneration()
}
Expand Down Expand Up @@ -131,15 +133,15 @@ final class Gifski {
delay: UInt16(100 / fps)
)
} catch {
completionHandlerOnce(.addFrameFailed(error as! GifskiWrapperError))
completionHandlerOnce(.addFrameFailed(error))
return
}

if result.isFinished {
do {
try gifski.endAddingFrames()
} catch {
completionHandlerOnce(.endAddingFramesFailed(error as! GifskiWrapperError))
completionHandlerOnce(.endAddingFramesFailed(error))
}
}
case .failure where result.isCancelled:
Expand All @@ -160,7 +162,7 @@ final class Gifski {
return
}

completionHandlerOnce(.writeFailed(error as! GifskiWrapperError))
completionHandlerOnce(.writeFailed(error))
}
}
}
Expand Down
14 changes: 10 additions & 4 deletions Gifski/MainWindowController.swift
Expand Up @@ -48,7 +48,7 @@ final class MainWindowController: NSWindowController {
self.conversionCompletedView.fileUrl = self.outUrl
self.conversionCompletedView.show()
self.videoDropView.isDropLabelHidden = true
} else if progress.isCancelled {
} else {
self.videoDropView.isHidden = false
self.videoDropView.fadeInVideoDropLabel()
}
Expand Down Expand Up @@ -179,7 +179,7 @@ final class MainWindowController: NSWindowController {
}

private var progress: Progress?
private lazy var timeEstimator = TimeRemainingEstimator(label: timeRemainingLabel)
private lazy var timeRemainingEstimator = TimeRemainingEstimator(label: timeRemainingLabel)

func startConversion(inputUrl: URL, outputUrl: URL) {
guard !isRunning else {
Expand All @@ -191,10 +191,12 @@ final class MainWindowController: NSWindowController {
isRunning = true

progress = Progress(totalUnitCount: 1)
progress?.publish()

circularProgress.progressInstance = progress
DockProgress.progressInstance = progress
timeEstimator.progress = progress
timeEstimator.start()
timeRemainingEstimator.progress = progress
timeRemainingEstimator.start()

progress?.performAsCurrent(withPendingUnitCount: 1) {
let conversion = Gifski.Conversion(
Expand All @@ -206,15 +208,19 @@ final class MainWindowController: NSWindowController {
)

Gifski.run(conversion) { error in
self.progress?.unpublish()
self.isRunning = false

if let error = error {
self.progress?.cancel()

switch error {
case .cancelled:
break
default:
self.presentError(error, modalFor: self.window)
}

return
}

Expand Down

0 comments on commit 0edd750

Please sign in to comment.