我正在使用Vapor,但这是一个纯粹的Swift问题。 Vapor的枚举“状态”定义为:(由于此代码已经很长,我在枚举中删除了一些案例)
public enum Status {
case `continue`
case switchingProtocols
case processing
case ok
case created
case accepted
case nonAuthoritativeInformation
case noContent
case resetContent
case partialContent
case multipleChoices
case movedPermanently
case found
case seeOther
case notModified
case useProxy
case switchProxy
case temporaryRedirect
case permanentRedirect
case badRequest
case unauthorized
case paymentRequired
case forbidden
case notFound
case methodNotAllowed
case notAcceptable
//removed a bunch of other 'cases' for the sake of brevity
case other(statusCode: Int, reasonPhrase: String)
}
extension Status {
public init?(officialCode: Int) {
switch officialCode {
case Status.`continue`.statusCode: self = .`continue`
case Status.switchingProtocols.statusCode: self = .switchingProtocols
case Status.processing.statusCode: self = .processing
case Status.ok.statusCode: self = .ok
case Status.created.statusCode: self = .created
case Status.accepted.statusCode: self = .accepted
case Status.nonAuthoritativeInformation.statusCode: self = .nonAuthoritativeInformation
case Status.noContent.statusCode: self = .noContent
case Status.resetContent.statusCode: self = .resetContent
case Status.partialContent.statusCode: self = .partialContent
case Status.multipleChoices.statusCode: self = .multipleChoices
case Status.movedPermanently.statusCode: self = .movedPermanently
case Status.found.statusCode: self = .found
case Status.seeOther.statusCode: self = .seeOther
case Status.notModified.statusCode: self = .notModified
case Status.useProxy.statusCode: self = .useProxy
case Status.switchProxy.statusCode: self = .switchProxy
case Status.temporaryRedirect.statusCode: self = .temporaryRedirect
case Status.permanentRedirect.statusCode: self = .permanentRedirect
case Status.badRequest.statusCode: self = .badRequest
case Status.unauthorized.statusCode: self = .unauthorized
case Status.paymentRequired.statusCode: self = .paymentRequired
case Status.forbidden.statusCode: self = .forbidden
case Status.notFound.statusCode: self = .notFound
case Status.methodNotAllowed.statusCode: self = .methodNotAllowed
case Status.notAcceptable.statusCode: self = .notAcceptable
default: return nil
}
}
public init(statusCode: Int, reasonPhrase: String? = nil) {
if let official = Status(officialCode: statusCode) {
self = official
} else {
self = .other(statusCode: statusCode, reasonPhrase: reasonPhrase ?? "")
}
}
}
extension Status {
public var statusCode: Int {
switch self {
case .`continue`: return 100
case .switchingProtocols: return 101
case .processing: return 102
case .ok: return 200
case .created: return 201
case .accepted: return 202
case .nonAuthoritativeInformation: return 203
case .noContent: return 204
case .resetContent: return 205
case .partialContent: return 206
case .multipleChoices: return 300
case .movedPermanently: return 301
case .found: return 302
case .seeOther: return 303
case .notModified: return 304
case .useProxy: return 305
case .switchProxy: return 306
case .temporaryRedirect: return 307
case .permanentRedirect: return 308
case .badRequest: return 400
case .unauthorized: return 401
case .paymentRequired: return 402
case .forbidden: return 403
case .notFound: return 404
case .methodNotAllowed: return 405
case .notAcceptable: return 406
case .other(let statusCode, _): return statusCode
}
}
}
extension Status {
public var reasonPhrase: String {
switch self {
case .`continue`: return "Continue"
case .switchingProtocols: return "Switching Protocols"
case .processing: return "Processing"
case .ok: return "OK"
case .created: return "Created"
case .accepted: return "Accepted"
case .nonAuthoritativeInformation: return "Non Authoritative Information"
case .noContent: return "No Content"
case .resetContent: return "Reset Content"
case .partialContent: return "Partial Content"
case .multipleChoices: return "Multiple Choices"
case .movedPermanently: return "Moved Permanently"
case .found: return "Found"
case .seeOther: return "See Other"
case .notModified: return "Not Modified"
case .useProxy: return "Use Proxy"
case .switchProxy: return "Switch Proxy"
case .temporaryRedirect: return "Temporary Redirect"
case .permanentRedirect: return "Permanent Redirect"
case .badRequest: return "Bad Request"
case .unauthorized: return "Unauthorized"
case .paymentRequired: return "Payment Required"
case .forbidden: return "Forbidden"
case .notFound: return "Not Found"
case .methodNotAllowed: return "Method Not Allowed"
case .notAcceptable: return "Not Acceptable"
case .other(_, let reasonPhrase): return reasonPhrase
}
}
}
extension Status: Hashable {
public var hashValue: Int {
return statusCode
}
}
public func ==(lhs: Status, rhs: Status) -> Bool {
return lhs.hashValue == rhs.hashValue
}
这个定义方式我可以做一个
let status = Status (.notFound)
并将其与throw:
一起使用throw Abort (status)
然后,throw将显示404错误,其中包含以下文本:“Not Found”。我想自定义该文本。但创建一个状态:
let status = Status(.notFound, reasonPhrase: "my own text")
仍会显示默认文字
我唯一能做的就是创建一个状态:
let status = Status(999, reasonPhrase: "my own text")
其中状态代码不是标准错误编号。
这可能令人困惑,不符合标准。你能告诉我如何在Swift中我可以覆盖此行为或扩展Status或...以便我能够使用自定义文本创建标准错误(例如404 = .notFound)
*编辑CRD解决方案中剩余的问题*
我添加了一个init扩展状态的文件: 扩展状态
extension Status {
public init(status: Status, customReason: String)
{
self = .other(statusCode: status.statusCode, reasonPhrase: customReason)
}
}
在我的代码中我使用它:
let status = Status(status: .notFound, customReason: "test")
throw Abort(status)
它仍然显示:我扔的html页面上没有找到404 +。 然后我添加了一个印刷品,就像CRD在操场上一样:
let status = Status(status: .notFound, customReason: "test")
print ("\(status.statusCode) : \(status.reasonPhrase)")
throw Abort(status)
打印显示:404:在控制台中测试,html错误页面显示404 + Not Found,就像之前一样。很显然,Vapor的中止功能正在操纵这个... grrrr
答案 0 :(得分:1)
如果我理解正确,您可以在扩展程序中添加第二个init
,该扩展程序接受Status
和自定义消息并返回.other
:
extension Status
{
public init(status: Status, customReason: String)
{
self = .other(statusCode: status.statusCode, reasonPhrase: customReason)
}
}
可以像:
一样使用let q = Status(status: .notFound, customReason: "This page has ceased to be")
<强>附录强>
在游乐场:
let p = Status(statusCode: Status.notFound.statusCode, reasonPhrase: "This page has ceased to be")
let q = Status(status: .notFound, customReason: "This page has ceased to be")
print("\(p.statusCode) : \(p.reasonPhrase)")
print("\(q.statusCode) : \(q.reasonPhrase)")
产生
404 : Not Found
404 : This page has ceased to be
HTH