Better gRPC reflection errors

This commit is contained in:
Gregory Schier
2024-06-18 10:54:39 -07:00
parent 5cdcbc8dce
commit f81ffe249e
3 changed files with 27 additions and 5 deletions

View File

@@ -189,7 +189,7 @@ impl GrpcHandle {
paths: Vec<PathBuf>, paths: Vec<PathBuf>,
) -> Result<Vec<ServiceDefinition>, String> { ) -> Result<Vec<ServiceDefinition>, String> {
let pool = fill_pool_from_files(&self.app_handle, paths).await?; let pool = fill_pool_from_files(&self.app_handle, paths).await?;
let uri = Uri::from_str(uri).map_err(|e| e.to_string())?; let uri = uri_from_str(uri)?;
self.pools.insert(self.get_pool_key(id, &uri), pool.clone()); self.pools.insert(self.get_pool_key(id, &uri), pool.clone());
Ok(self.services_from_pool(&pool)) Ok(self.services_from_pool(&pool))
} }
@@ -198,7 +198,7 @@ impl GrpcHandle {
id: &str, id: &str,
uri: &str, uri: &str,
) -> Result<Vec<ServiceDefinition>, String> { ) -> Result<Vec<ServiceDefinition>, String> {
let uri = Uri::from_str(uri).map_err(|e| e.to_string())?; let uri = uri_from_str(uri)?;
let pool = fill_pool(&uri).await?; let pool = fill_pool(&uri).await?;
self.pools.insert(self.get_pool_key(id, &uri), pool.clone()); self.pools.insert(self.get_pool_key(id, &uri), pool.clone());
Ok(self.services_from_pool(&pool)) Ok(self.services_from_pool(&pool))
@@ -239,7 +239,7 @@ impl GrpcHandle {
uri: &str, uri: &str,
proto_files: Vec<PathBuf>, proto_files: Vec<PathBuf>,
) -> Result<GrpcConnection, String> { ) -> Result<GrpcConnection, String> {
let uri = Uri::from_str(uri).map_err(|e| e.to_string())?; let uri = uri_from_str(uri)?;
let pool = match self.pools.get(id) { let pool = match self.pools.get(id) {
Some(p) => p.clone(), Some(p) => p.clone(),
None => match proto_files.len() { None => match proto_files.len() {
@@ -267,3 +267,13 @@ fn decorate_req<T>(metadata: HashMap<String, String>, req: &mut Request<T>) -> R
} }
Ok(()) Ok(())
} }
fn uri_from_str(uri_str: &str) -> Result<Uri, String> {
match Uri::from_str(uri_str) {
Ok(uri) => Ok(uri),
Err(err) => {
// Uri::from_str basically only returns "invalid format" so we add more context here
Err(format!("Failed to parse URL, {}", err.to_string()))
},
}
}

View File

@@ -134,6 +134,12 @@ async fn cmd_grpc_reflect(
let req = get_grpc_request(&window, request_id) let req = get_grpc_request(&window, request_id)
.await .await
.map_err(|e| e.to_string())?; .map_err(|e| e.to_string())?;
// Short-circuit if no URL is set
if req.url.is_empty() {
return Ok(Vec::new());
}
let uri = safe_uri(req.url.as_str()); let uri = safe_uri(req.url.as_str());
if proto_files.len() > 0 { if proto_files.len() > 0 {
grpc_handle grpc_handle

View File

@@ -5,7 +5,6 @@ import { useGrpcRequest } from '../hooks/useGrpcRequest';
import { count } from '../lib/pluralize'; import { count } from '../lib/pluralize';
import { Banner } from './core/Banner'; import { Banner } from './core/Banner';
import { Button } from './core/Button'; import { Button } from './core/Button';
import { FormattedError } from './core/FormattedError';
import { IconButton } from './core/IconButton'; import { IconButton } from './core/IconButton';
import { InlineCode } from './core/InlineCode'; import { InlineCode } from './core/InlineCode';
import { Link } from './core/Link'; import { Link } from './core/Link';
@@ -129,7 +128,14 @@ export function GrpcProtoSelection({ requestId }: Props) {
</tbody> </tbody>
</table> </table>
)} )}
{reflectError && <FormattedError>{reflectError}</FormattedError>} {reflectError && (
<Banner color="warning">
<h1 className="font-bold">
Reflection failed on URL <InlineCode>{request.url}</InlineCode>
</h1>
{reflectError}
</Banner>
)}
{reflectionUnimplemented && protoFiles.length === 0 && ( {reflectionUnimplemented && protoFiles.length === 0 && (
<Banner> <Banner>
<InlineCode>{request.url}</InlineCode> doesn&apos;t implement{' '} <InlineCode>{request.url}</InlineCode> doesn&apos;t implement{' '}