Refactor errors
This commit is contained in:
parent
6fbf8f44b7
commit
c7eb2b0176
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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<()> {
|
||||
|
|
|
@ -9,7 +9,7 @@ extension S3Adapter {
|
|||
}
|
||||
|
||||
if response.http.status == .notFound {
|
||||
return FilesystemError.notFound
|
||||
return FilesystemError.notFound(path)
|
||||
}
|
||||
|
||||
return error
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue