File: Error.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (201 lines) | stat: -rw-r--r-- 7,429 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

/// A convenience wrapper for `Result` where the error is a `ResponseError`.
public typealias LSPResult<T> = Swift.Result<T, ResponseError>

/// Error code suitable for use between language server and client.
public struct ErrorCode: RawRepresentable, Codable, Hashable, Sendable {

  public var rawValue: Int

  public init(rawValue: Int) {
    self.rawValue = rawValue
  }

  // MARK: JSON RPC
  public static let parseError: ErrorCode = ErrorCode(rawValue: -32700)
  public static let invalidRequest: ErrorCode = ErrorCode(rawValue: -32600)
  public static let methodNotFound: ErrorCode = ErrorCode(rawValue: -32601)
  public static let invalidParams: ErrorCode = ErrorCode(rawValue: -32602)
  public static let internalError: ErrorCode = ErrorCode(rawValue: -32603)

  /// This is the start range of JSON-RPC reserved error codes.
  /// It doesn't denote a real error code. No LSP error codes should
  /// be defined between the start and end range. For backwards
  /// compatibility the `ServerNotInitialized` and the `UnknownErrorCode`
  /// are left in the range.
  public static let jsonrpcReservedErrorRangeStart = ErrorCode(rawValue: -32099)
  public static let serverErrorStart: ErrorCode = jsonrpcReservedErrorRangeStart

  /// Error code indicating that a server received a notification or
  /// request before the server has received the `initialize` request.
  public static let serverNotInitialized = ErrorCode(rawValue: -32002)
  public static let unknownErrorCode = ErrorCode(rawValue: -32001)

  /// This is the end range of JSON-RPC reserved error codes.
  /// It doesn't denote a real error code.
  public static let jsonrpcReservedErrorRangeEnd = ErrorCode(rawValue: -32000)
  /// Deprecated, use jsonrpcReservedErrorRangeEnd
  public static let serverErrorEnd = jsonrpcReservedErrorRangeEnd

  /// This is the start range of LSP reserved error codes.
  /// It doesn't denote a real error code.
  public static let lspReservedErrorRangeStart = ErrorCode(rawValue: -32899)

  /// A request failed but it was syntactically correct, e.g the
  /// method name was known and the parameters were valid. The error
  /// message should contain human readable information about why
  /// the request failed.
  public static let requestFailed = ErrorCode(rawValue: -32803)

  /// The server cancelled the request. This error code should
  /// only be used for requests that explicitly support being
  /// server cancellable.
  public static let serverCancelled = ErrorCode(rawValue: -32802)

  /// The server detected that the content of a document got
  /// modified outside normal conditions. A server should
  /// NOT send this error code if it detects a content change
  /// in it unprocessed messages. The result even computed
  /// on an older state might still be useful for the client.
  ///
  /// If a client decides that a result is not of any use anymore
  /// the client should cancel the request.
  public static let contentModified = ErrorCode(rawValue: -32801)

  /// The client has canceled a request and a server as detected
  /// the cancel.
  public static let cancelled: ErrorCode = ErrorCode(rawValue: -32800)

  /// This is the end range of LSP reserved error codes.
  /// It doesn't denote a real error code.
  public static let lspReservedErrorRangeEnd = ErrorCode(rawValue: -32800)

  // MARK: SourceKit-LSP specific error codes
  public static let workspaceNotOpen: ErrorCode = ErrorCode(rawValue: -32003)
}

/// An error response represented by a code and message.
public struct ResponseError: Error, Codable, Hashable {
  public var code: ErrorCode
  public var message: String
  // FIXME: data

  public init(code: ErrorCode, message: String) {
    self.code = code
    self.message = message
  }
}

extension ResponseError {
  // MARK: Convenience properties for common errors.

  public static let cancelled: ResponseError = ResponseError(code: .cancelled, message: "request cancelled by client")

  public static let serverCancelled: ResponseError = ResponseError(
    code: .serverCancelled,
    message: "request cancelled by server"
  )

  public static func workspaceNotOpen(_ uri: DocumentURI) -> ResponseError {
    return ResponseError(code: .workspaceNotOpen, message: "No workspace containing '\(uri)' found")
  }

  public static func methodNotFound(_ method: String) -> ResponseError {
    return ResponseError(code: .methodNotFound, message: "method not found: \(method)")
  }

  public static func unknown(_ message: String) -> ResponseError {
    return ResponseError(code: .unknownErrorCode, message: message)
  }

  public static func internalError(_ message: String) -> ResponseError {
    return ResponseError(code: .internalError, message: message)
  }
}

/// An error during message decoding.
public struct MessageDecodingError: Error, Hashable {

  /// The error code.
  public var code: ErrorCode

  /// A free-form description of the error.
  public var message: String

  /// If it was possible to recover the request id, it is stored here. This can be used e.g. to reply with a `ResponseError` to invalid requests.
  public var id: RequestID?

  public enum MessageKind: Sendable {
    case request
    case response
    case notification
    case unknown
  }

  /// What kind of message was being decoded, or `.unknown`.
  public var messageKind: MessageKind

  public init(code: ErrorCode, message: String, id: RequestID? = nil, messageKind: MessageKind = .unknown) {
    self.code = code
    self.message = message
    self.id = id
    self.messageKind = messageKind
  }
}

extension MessageDecodingError {
  public static func methodNotFound(
    _ method: String,
    id: RequestID? = nil,
    messageKind: MessageKind = .unknown
  ) -> MessageDecodingError {
    return MessageDecodingError(
      code: .methodNotFound,
      message: "method not found: \(method)",
      id: id,
      messageKind: messageKind
    )
  }

  public static func invalidRequest(
    _ reason: String,
    id: RequestID? = nil,
    messageKind: MessageKind = .unknown
  ) -> MessageDecodingError {
    return MessageDecodingError(code: .invalidRequest, message: reason, id: id, messageKind: messageKind)
  }

  public static func invalidParams(
    _ reason: String,
    id: RequestID? = nil,
    messageKind: MessageKind = .unknown
  ) -> MessageDecodingError {
    return MessageDecodingError(code: .invalidParams, message: reason, id: id, messageKind: messageKind)
  }

  public static func parseError(
    _ reason: String,
    id: RequestID? = nil,
    messageKind: MessageKind = .unknown
  ) -> MessageDecodingError {
    return MessageDecodingError(code: .parseError, message: reason, id: id, messageKind: messageKind)
  }
}

extension ResponseError {
  /// Converts a `MessageDecodingError` to a `ResponseError`.
  public init(_ decodingError: MessageDecodingError) {
    self.init(code: decodingError.code, message: decodingError.message)
  }
}