Skip to content

Commit b9e93f7

Browse files
add logging of failure cases to DocCCatalogIndexManager
1 parent c1895c3 commit b9e93f7

File tree

1 file changed

+35
-6
lines changed

1 file changed

+35
-6
lines changed

Sources/DocCDocumentation/DocCCatalogIndexManager.swift

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
package import Foundation
14+
import SKLogging
1415
@_spi(LinkCompletion) @preconcurrency import SwiftDocC
1516

1617
final actor DocCCatalogIndexManager {
@@ -51,6 +52,10 @@ final actor DocCCatalogIndexManager {
5152
catalogToIndexMap[catalogURL] = .success(catalogIndex)
5253
return catalogIndex
5354
} catch {
55+
// Don't cache cancellation errors
56+
guard !(error is CancellationError) else {
57+
throw .cancelled
58+
}
5459
let internalError = error as? DocCIndexError ?? DocCIndexError.internalError(error)
5560
catalogToIndexMap[catalogURL] = .failure(internalError)
5661
throw internalError
@@ -62,13 +67,16 @@ final actor DocCCatalogIndexManager {
6267
package enum DocCIndexError: LocalizedError {
6368
case internalError(any Error)
6469
case unexpectedlyNilRenderReferenceStore
70+
case cancelled
6571

6672
package var errorDescription: String? {
6773
switch self {
6874
case .internalError(let internalError):
6975
return "An internal error occurred: \(internalError.localizedDescription)"
7076
case .unexpectedlyNilRenderReferenceStore:
7177
return "Did not receive a RenderReferenceStore from the DocC server"
78+
case .cancelled:
79+
return "The request was cancelled"
7280
}
7381
}
7482
}
@@ -101,7 +109,9 @@ package struct DocCCatalogIndex: Sendable {
101109
var assets: [String: DataAsset] = [:]
102110
for (reference, asset) in renderReferenceStore.assets {
103111
var asset = asset
104-
asset.variants = asset.variants.compactMapValues { $0.withScheme("doc-asset") }
112+
asset.variants = asset.variants.compactMapValues { url in
113+
orLog("Failed to convert asset from RenderReferenceStore") { try url.withScheme("doc-asset") }
114+
}
105115
assets[reference.assetName] = asset
106116
}
107117
self.assets = assets
@@ -126,7 +136,7 @@ package struct DocCCatalogIndex: Sendable {
126136
case .overview:
127137
tutorialOverviews[lastPathComponent] = topicRenderReference
128138
default:
129-
guard topicContentValue.isDocumentationExtensionContent else {
139+
guard topicContentValue.isDocumentationExtensionContent, renderReferenceKey.url.pathComponents.count > 2 else {
130140
continue
131141
}
132142
// Documentation extensions are always of the form `doc://<BundleID>/documentation/<SymbolPath>`.
@@ -145,10 +155,29 @@ package struct DocCCatalogIndex: Sendable {
145155
}
146156
}
147157

158+
fileprivate enum WithSchemeError: LocalizedError {
159+
case failedToRetrieveComponents(URL)
160+
case failedToEncode(URLComponents)
161+
162+
var errorDescription: String? {
163+
switch self {
164+
case .failedToRetrieveComponents(let url):
165+
"Failed to retrieve components for URL \(url.absoluteString)"
166+
case .failedToEncode(let components):
167+
"Failed to encode URL components \(String(reflecting: components))"
168+
}
169+
}
170+
}
171+
148172
fileprivate extension URL {
149-
func withScheme(_ scheme: String) -> URL {
150-
var components = URLComponents(url: self, resolvingAgainstBaseURL: true)
151-
components?.scheme = scheme
152-
return components?.url ?? self
173+
func withScheme(_ scheme: String) throws(WithSchemeError) -> URL {
174+
guard var components = URLComponents(url: self, resolvingAgainstBaseURL: true) else {
175+
throw WithSchemeError.failedToRetrieveComponents(self)
176+
}
177+
components.scheme = scheme
178+
guard let result = components.url else {
179+
throw WithSchemeError.failedToEncode(components)
180+
}
181+
return result
153182
}
154183
}

0 commit comments

Comments
 (0)