Refactor errors

This commit is contained in:
Zdenek Topic 2018-10-23 19:57:49 +02:00
parent 6fbf8f44b7
commit c7eb2b0176
No known key found for this signature in database
GPG Key ID: 41897C1A6A09DEF5
15 changed files with 67 additions and 74 deletions

View File

@ -14,7 +14,7 @@ public protocol FilesystemReading {
func has(file: String, on: Container, options: FileOptions) -> Future<Bool>
func read(file: String, on: Container, options: FileOptions) -> Future<Data>
func metadata(of: String, on: Container, options: FileOptions) -> Future<FileMetadataConvertible>
func size(of: String, on: Container, options: FileOptions) -> Future<Int>
func size(of: String, on: Container, options: FileOptions) -> Future<Int?>
func mediaType(of: String, on: Container, options: FileOptions) -> Future<MediaType>
}
@ -42,11 +42,11 @@ extension FilesystemReading {
public func mediaType(of file: String) throws -> MediaType {
guard let ext = self.ext(of: file) else {
throw FilesystemError.unresolvableMediaType
throw MediaTypeError.unresolvable(file)
}
guard let mediaType = MediaType.fileExtension(ext) else {
throw FilesystemError.unresolvableMediaType
throw MediaTypeError.unresolvable(file)
}
return mediaType

View File

@ -5,16 +5,16 @@ extension LocalAdapter: FilesystemReading {
public func has(file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<Bool> {
return run(on: worker) {
let path = self.absolutePath(to: file)
let path = try self.absolutePath(to: file)
return self.fileManager.fileExists(atPath: path)
}
}
public func read(file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<Data> {
return run(on: worker) {
let path = self.absolutePath(to: file)
let path = try self.absolutePath(to: file)
guard let data = self.fileManager.contents(atPath: path) else {
throw FilesystemError.notFound
throw FilesystemError.notFound(path)
}
return data
@ -23,7 +23,7 @@ extension LocalAdapter: FilesystemReading {
public func metadata(of file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<FileMetadataConvertible> {
return run(on: worker) {
let path = self.absolutePath(to: file)
let path = try self.absolutePath(to: file)
let attributes = try self.fileManager.attributesOfItem(atPath: path)
var meta = try attributes.fileMetadata()
try meta.set(key: .mime, to: self.mediaType(of: file).description)
@ -31,14 +31,10 @@ extension LocalAdapter: FilesystemReading {
}
}
public func size(of file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<Int> {
public func size(of file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<Int?> {
return metadata(of: file, on: worker, options: .empty)
.map { meta in
guard let size = try meta.fileMetadata().size else {
throw FilesystemError.fileSizeNotAvailable
}
return size
return try meta.fileMetadata().size
}
}

View File

@ -5,9 +5,9 @@ extension LocalAdapter: FilesystemWriting {
public func write(data: Data, to file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {
return run(on: worker) {
let path = self.absolutePath(to: file)
let path = try self.absolutePath(to: file)
guard self.fileManager.createFile(atPath: path, contents: data, attributes: nil) else {
throw FilesystemError.creationFailed
throw FilesystemError.creationFailed(path)
}
return ()
@ -16,12 +16,12 @@ extension LocalAdapter: FilesystemWriting {
public func update(data: Data, to file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {
return run(on: worker) {
let path = self.absolutePath(to: file)
let path = try self.absolutePath(to: file)
let fileURL = URL(fileURLWithPath: path)
// Check if file exists
guard try self.has(file: file, on: worker, options: options).wait() else {
throw FilesystemError.notFound
throw FilesystemError.notFound(path)
}
// Saving to temp file
@ -46,7 +46,7 @@ extension LocalAdapter: FilesystemWriting {
public func move(file: String, to newName: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {
return run(on: worker) {
let path = self.absolutePath(to: file)
let path = try self.absolutePath(to: file)
let fileURL = URL(fileURLWithPath: path)
let dir = fileURL.deletingLastPathComponent()
let newURL = dir.appendingPathComponent(newName, isDirectory: false)
@ -58,8 +58,8 @@ extension LocalAdapter: FilesystemWriting {
public func copy(file: String, to newFile: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {
return run(on: worker) {
let path = self.absolutePath(to: file)
let newPath = self.absolutePath(to: file)
let path = try self.absolutePath(to: file)
let newPath = try self.absolutePath(to: file)
try self.fileManager.copyItem(atPath: path, toPath: newPath)
return ()
}
@ -67,7 +67,7 @@ extension LocalAdapter: FilesystemWriting {
public func delete(file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {
return run(on: worker) {
let path = self.absolutePath(to: file)
let path = try self.absolutePath(to: file)
try self.fileManager.removeItem(atPath: path)
return ()
}
@ -75,7 +75,7 @@ extension LocalAdapter: FilesystemWriting {
public func delete(directory: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {
return run(on: worker) {
let path = self.absolutePath(to: directory)
let path = try self.absolutePath(to: directory)
try self.fileManager.removeItem(atPath: path)
return ()
}
@ -83,7 +83,7 @@ extension LocalAdapter: FilesystemWriting {
public func create(directory: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {
return run(on: worker) {
let path = self.absolutePath(to: directory)
let path = try self.absolutePath(to: directory)
try self.fileManager.createDirectory(atPath: path, withIntermediateDirectories: true, attributes: nil)
return ()
}

View File

@ -19,8 +19,8 @@ public struct LocalAdapter {
self.queueFactory = queueFactory
}
public func absolutePath(to path: String) -> String {
let prefixed = PathTools.applyPrefix(config.root, to: path)
public func absolutePath(to path: String) throws -> String {
let prefixed = try PathTools.applyPrefix(config.root, to: path)
return URL(fileURLWithPath: prefixed).absoluteString
}

View File

@ -10,19 +10,19 @@ public struct NullAdapter {
extension NullAdapter: FilesystemReading {
public func read(file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<Data> {
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound)
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound(file))
}
public func metadata(of file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<FileMetadataConvertible> {
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound)
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound(file))
}
public func size(of file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<Int> {
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound)
public func size(of file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<Int?> {
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound(file))
}
public func timestamp(of file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<Date> {
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound)
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound(file))
}
@ -40,23 +40,23 @@ extension NullAdapter: FilesystemWriting {
}
public func update(data: Data, to file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound)
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound(file))
}
public func move(file: String, to: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound)
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound(file))
}
public func copy(file: String, to: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound)
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound(file))
}
public func delete(file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound)
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound(file))
}
public func delete(directory: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound)
return worker.eventLoop.newFailedFuture(error: FilesystemError.notFound(directory))
}
public func create(directory: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {

View File

@ -9,7 +9,7 @@ extension S3Adapter {
}
if response.http.status == .notFound {
return FilesystemError.notFound
return FilesystemError.notFound(path)
}
return error

View File

@ -25,11 +25,10 @@ extension S3Adapter: FilesystemReading {
}
}
public func size(of file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<Int> {
public func size(of file: String, on worker: Container, options: FileOptions) -> EventLoopFuture<Int?> {
return run(path: file, on: worker) {
return try self.client.get(fileInfo: $0, on: worker)
.map { $0.size }
.unwrap(or: FilesystemError.fileSizeNotAvailable)
}
}

View File

@ -4,14 +4,14 @@ import Vapor
extension S3Adapter: FilesystemWriting, FileOverwriteSupporting {
public func write(data: Data, to: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {
return run(path: to, on: worker) {
return run(path: to, on: worker) { file in
let s3Options = try options.s3()
let upload = try self.fileUpload(data: data, to: $0, options: s3Options)
let upload = try self.fileUpload(data: data, to: file, options: s3Options)
return self.has(file: $0.path, on: worker, options: options)
return self.has(file: file.path, on: worker, options: options)
.flatMap { has -> Future<()> in
guard !has else {
throw FilesystemError.alreadyExists
throw FilesystemError.alreadyExists(file.path)
}
return try self.client.put(file: upload, on: worker)
@ -21,14 +21,14 @@ extension S3Adapter: FilesystemWriting, FileOverwriteSupporting {
}
public func update(data: Data, to: String, on worker: Container, options: FileOptions) -> EventLoopFuture<()> {
return run(path: to, on: worker) {
return run(path: to, on: worker) { file in
let s3Options = try options.s3()
let upload = try self.fileUpload(data: data, to: $0, options: s3Options)
let upload = try self.fileUpload(data: data, to: file, options: s3Options)
return self.has(file: $0.path, on: worker, options: options)
return self.has(file: file.path, on: worker, options: options)
.flatMap { has -> Future<()> in
guard has else {
throw FilesystemError.notFound
throw FilesystemError.notFound(file.path)
}
return try self.client.put(file: upload, on: worker)

View File

@ -54,7 +54,7 @@ extension Filesystem {
}.map { try $0.fileMetadata() }
}
public func size(of file: String, options: FileOptionsConvertible?) -> Future<Int> {
public func size(of file: String, options: FileOptionsConvertible?) -> Future<Int?> {
return PathTools.normalize(path: file, on: worker)
.flatMap { path in
try self.adapter.size(

View File

@ -43,7 +43,7 @@ public extension Filesystem {
)
}
throw FilesystemError.noFileOverrideSupport
throw FilesystemError.fileOverrideUnsupported(by: self.adapter)
}
return try self.adapter.write(
@ -70,7 +70,7 @@ public extension Filesystem {
func rename(file: String, to: String, options: FileOptionsConvertible?) -> Future<()> {
guard var path = URL(string: file) else {
return worker.eventLoop.newFailedFuture(error: FilesystemError.invalidPath)
return worker.eventLoop.newFailedFuture(error: PathError.invalid(file))
}
path.deleteLastPathComponent()
@ -107,7 +107,7 @@ public extension Filesystem {
return PathTools.normalize(path: directory, on: worker)
.map { path in
if path == "" {
throw FilesystemError.rootViolation
throw PathError.rootViolation
}
return path

View File

@ -1,21 +1,17 @@
import Foundation
public enum MediaTypeError: Swift.Error {
case unresolvable(String)
}
public enum FilesystemError: Swift.Error {
case notFound
case alreadyExists
case unresolvableMediaType
case invalidPath
case notFound(String)
case alreadyExists(String)
case creationFailed
case creationFailed(String)
case timestampNotAvailable
case fileSizeNotAvailable
case cantConstructURLfromPath(String)
case pathOutsideOfRoot(String)
case noFileOverrideSupport
case rootViolation
case fileOverrideUnsupported(by: FilesystemAdapting)
case listingUnsupported(by: FilesystemAdapting)

View File

@ -24,7 +24,7 @@ extension FilesystemForwarding {
return self.filesystem.metadata(of: of, options: options)
}
public func size(of: String, options: FileOptionsConvertible?) -> EventLoopFuture<Int> {
public func size(of: String, options: FileOptionsConvertible?) -> EventLoopFuture<Int?> {
return self.filesystem.size(of: of, options: options)
}

View File

@ -7,7 +7,7 @@ public protocol FilesystemOperating {
func read(file: String, options: FileOptionsConvertible?) -> Future<Data>
func listContents(of: String, recursive: Bool, options: FileOptionsConvertible?) -> Future<[String]>
func metadata(of: String, options: FileOptionsConvertible?) -> Future<FileMetadata>
func size(of: String, options: FileOptionsConvertible?) -> Future<Int>
func size(of: String, options: FileOptionsConvertible?) -> Future<Int?>
func write(data: Data, to: String, options: FileOptionsConvertible?) -> Future<()>
// func write(file: String, to: String) -> Future<()>
func update(data: Data, to: String, options: FileOptionsConvertible?) -> Future<()>
@ -45,7 +45,7 @@ extension FilesystemOperating {
return metadata(of: of, options: nil)
}
func size(of: String) -> Future<Int> {
func size(of: String) -> Future<Int?> {
return size(of: of, options: nil)
}

View File

@ -1,5 +1,11 @@
import Foundation
public enum PathError: Swift.Error {
case invalid(String)
case outsideOfRoot(String)
case rootViolation
}
public enum PathTools {
public static func normalize(path: String) throws -> String {
@ -7,7 +13,7 @@ public enum PathTools {
normalized = normalized.trimmingCharacters(in: .whitespacesAndNewlines)
guard let url = URL(string: normalized) else {
throw FilesystemError.cantConstructURLfromPath(path)
throw PathError.invalid(path)
}
var parts: [String] = []
@ -17,7 +23,7 @@ public enum PathTools {
case ".": break
case "..":
guard !parts.isEmpty else {
throw FilesystemError.pathOutsideOfRoot(path)
throw PathError.outsideOfRoot(path)
}
parts.removeLast()
@ -38,9 +44,9 @@ public enum PathTools {
}
}
public static func applyPrefix(_ prefix: String, to path: String) -> String {
public static func applyPrefix(_ prefix: String, to path: String) throws -> String {
guard let prefixed = URL(string: path, relativeTo: URL(string: prefix)) else {
fatalError("Cannot create prefixed URL")
throw PathError.invalid(path)
}
return prefixed.absoluteString

View File

@ -73,11 +73,7 @@ fileprivate class DummyAdapter: FilesystemAdapting {
fatalError()
}
func size(of: String, on: Container, options: FileOptions) -> EventLoopFuture<Int> {
fatalError()
}
func timestamp(of: String, on: Container, options: FileOptions) -> EventLoopFuture<Date> {
func size(of: String, on: Container, options: FileOptions) -> EventLoopFuture<Int?> {
fatalError()
}