Skip to content

Commit

Permalink
Merge branch 'main' into v2/foundation-essentials
Browse files Browse the repository at this point in the history
  • Loading branch information
glbrntt authored Dec 17, 2024
2 parents 96e3e58 + e431ed6 commit a8222c3
Show file tree
Hide file tree
Showing 9 changed files with 740 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Examples/error-details/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.DS_Store
/.build
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
37 changes: 37 additions & 0 deletions Examples/error-details/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// swift-tools-version:6.0
/*
* Copyright 2024, gRPC Authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import PackageDescription

let package = Package(
name: "error-details",
platforms: [.macOS(.v15)],
dependencies: [
.package(url: "https://github.com/grpc/grpc-swift.git", branch: "main"),
.package(url: "https://github.com/grpc/grpc-swift-protobuf.git", branch: "main"),
],
targets: [
.executableTarget(
name: "error-details",
dependencies: [
.product(name: "GRPCCore", package: "grpc-swift"),
.product(name: "GRPCInProcessTransport", package: "grpc-swift"),
.product(name: "GRPCProtobuf", package: "grpc-swift-protobuf"),
]
)
]
)
26 changes: 26 additions & 0 deletions Examples/error-details/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Detailed Error

This example demonstrates how to create and unpack detailed errors.

## Overview

A command line tool that demonstrates how a detailed error can be thrown by a
service and unpacked and inspected by a client. The detailed error model is
described in more detailed in the [gRPC Error
Guide](https://grpc.io/docs/guides/error/) and is made available via the
[grpc-swift-protobuf](https://github.com/grpc-swift-protobuf) package.

## Usage

Build and run the example using the CLI:

```console
$ swift run
Error code: resourceExhausted
Error message: The greeter has temporarily run out of greetings.
Error details:
- Localized message (en-GB): Out of enthusiasm. The greeter is having a cup of tea, try again after that.
- Localized message (en-US): Out of enthusiasm. The greeter is taking a coffee break, try again later.
- Help links:
- https://en.wikipedia.org/wiki/Caffeine (A Wikipedia page about caffeine including its properties and effects.)
```
85 changes: 85 additions & 0 deletions Examples/error-details/Sources/DetailedErrorExample.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright 2024, gRPC Authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import GRPCCore
import GRPCInProcessTransport
import GRPCProtobuf

@main
struct DetailedErrorExample {
static func main() async throws {
let inProcess = InProcessTransport()
try await withGRPCServer(transport: inProcess.server, services: [Greeter()]) { server in
try await withGRPCClient(transport: inProcess.client) { client in
try await Self.doRPC(Helloworld_Greeter.Client(wrapping: client))
}
}
}

static func doRPC(_ greeter: Helloworld_Greeter.Client) async throws {
do {
let reply = try await greeter.sayHello(.with { $0.name = "(ignored)" })
print("Unexpected reply: \(reply.message)")
} catch let error as RPCError {
// Unpack the detailed from the standard 'RPCError'.
guard let status = try error.unpackGoogleRPCStatus() else { return }
print("Error code: \(status.code)")
print("Error message: \(status.message)")
print("Error details:")
for detail in status.details {
if let localizedMessage = detail.localizedMessage {
print("- Localized message (\(localizedMessage.locale)): \(localizedMessage.message)")
} else if let help = detail.help {
print("- Help links:")
for link in help.links {
print(" - \(link.url) (\(link.linkDescription))")
}
}
}
}
}
}

struct Greeter: Helloworld_Greeter.SimpleServiceProtocol {
func sayHello(
request: Helloworld_HelloRequest,
context: ServerContext
) async throws -> Helloworld_HelloReply {
// Always throw a detailed error.
throw GoogleRPCStatus(
code: .resourceExhausted,
message: "The greeter has temporarily run out of greetings.",
details: [
.localizedMessage(
locale: "en-GB",
message: "Out of enthusiasm. The greeter is having a cup of tea, try again after that."
),
.localizedMessage(
locale: "en-US",
message: "Out of enthusiasm. The greeter is taking a coffee break, try again later."
),
.help(
links: [
ErrorDetails.Help.Link(
url: "https://en.wikipedia.org/wiki/Caffeine",
description: "A Wikipedia page about caffeine including its properties and effects."
)
]
),
]
)
}
}
Loading

0 comments on commit a8222c3

Please sign in to comment.