Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions CosmosDBShell.Tests/CommandTests/ConnectCommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,32 @@ public void ConnectCommand_VSCodeCredentialOption_DoesNotProduceUnknownOptionDia
Assert.DoesNotContain(model.Diagnostics, diagnostic => diagnostic.Code == "SEM002");
}

[Fact]
public void LocalEmulatorConnectionFailureMessage_ExplainsCommonCauses()
{
var endpoint = new Uri("https://localhost:8081/");
var message = ShellInterpreter.GetLocalEmulatorConnectionFailureMessage(endpoint);

Assert.Contains("Cosmos DB emulator at https://localhost:8081/", message, StringComparison.OrdinalIgnoreCase);
Assert.Contains("http://localhost:8081/", message, StringComparison.OrdinalIgnoreCase);
Assert.Contains("--protocol [https|http]", message, StringComparison.OrdinalIgnoreCase);
Assert.Contains("https://learn.microsoft.com/en-us/azure/cosmos-db/emulator-linux", message, StringComparison.OrdinalIgnoreCase);
Assert.Contains("docker ps", message, StringComparison.OrdinalIgnoreCase);
Assert.Contains("http://localhost:8080/alive", message, StringComparison.OrdinalIgnoreCase);
Assert.Contains("mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator", message, StringComparison.OrdinalIgnoreCase);
Assert.Contains("docker run", message, StringComparison.OrdinalIgnoreCase);
}

[Fact]
public void LocalEmulatorConnectionFailureMessage_SuggestsHttpsWhenHttpFails()
{
var endpoint = new Uri("http://localhost:8081/");
var message = ShellInterpreter.GetLocalEmulatorConnectionFailureMessage(endpoint);

Assert.Contains("Cosmos DB emulator at http://localhost:8081/", message, StringComparison.OrdinalIgnoreCase);
Assert.Contains("https://localhost:8081/", message, StringComparison.OrdinalIgnoreCase);
}

private static async Task<ConnectCommand> BindConnectCommandAsync(string commandText)
{
var parser = new StatementParser(commandText);
Expand Down
27 changes: 27 additions & 0 deletions CosmosDBShell/Azure.Data.Cosmos.Shell.Core/ShellInterpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,11 @@ internal async Task ConnectAsync(string connectionString, string? loginHint = nu
catch (Exception ex)
{
client.Dispose();
if (isEmulator)
{
throw new ShellException(GetLocalEmulatorConnectionFailureMessage(client.Endpoint), ex);
}

throw new ShellException(MessageService.GetString("error-connection_failed"), ex);
}

Expand Down Expand Up @@ -903,6 +908,28 @@ private static async Task<AccountProperties> ReadAccountAsync(CosmosClient clien
return await client.ReadAccountAsync().WaitAsync(token);
}

internal static string GetLocalEmulatorConnectionFailureMessage(Uri endpoint)
{
var alternate = BuildAlternateEmulatorUri(endpoint);
return MessageService.GetArgsString(
"error-emulator_connection_failed",
"endpoint",
endpoint.ToString(),
"alternate",
alternate.ToString());
}

private static Uri BuildAlternateEmulatorUri(Uri endpoint)
{
var builder = new UriBuilder(endpoint)
{
Scheme = string.Equals(endpoint.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)
? Uri.UriSchemeHttp
: Uri.UriSchemeHttps,
};
return builder.Uri;
}

/// <summary>
/// Connects to a client & disposes old state.
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions CosmosDBShell/lang/en.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ no_char = N

error = Error:
error-connection_failed = Failed to connect to the Cosmos DB account.
error-emulator_connection_failed =
Could not reach the Cosmos DB emulator at { $endpoint }.
Make sure the emulator container is running ('docker ps') and reachable.
Tip: the Linux emulator exposes a health probe at http://localhost:8080/alive that can be used to verify it is up.
The Cosmos DB SDKs (including this shell) require HTTPS, but the Linux emulator defaults to HTTP.
Restart the container with --protocol [https|http], for example:
docker run -d -p 8081:8081 -p 1234:1234 -p 8080:8080 mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:vnext-preview --protocol https
Or, if you intentionally started the emulator with the other protocol, try connecting to { $alternate } instead.
See: https://learn.microsoft.com/en-us/azure/cosmos-db/emulator-linux
error-command-not-found = '{ $command }' is not recognized as an internal or external command, operable program or batch file.
error-shell-not-initialized = Shell is not initialized
error-start_process = Failed to start the process.
Expand Down
Loading