Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[auto] detect concurrent update error from local backend #11146

Merged
merged 1 commit into from Oct 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,4 @@
changes:
- type: fix
scope: auto/dotnet,go,nodejs,python
description: detect concurrent update error from local backend.
Expand Up @@ -23,11 +23,13 @@ internal CommandException(string name, CommandResult result)
private static readonly Regex _notFoundRegexPattern = new Regex("no stack named.*found");
private static readonly Regex _alreadyExistsRegexPattern = new Regex("stack.*already exists");
private static readonly string _conflictText = "[409] Conflict: Another update is currently in progress.";
private static readonly string _localBackendConflictText = "the stack is currently locked by";

internal static CommandException CreateFromResult(CommandResult result)
=> _notFoundRegexPattern.IsMatch(result.StandardError) ? new StackNotFoundException(result)
: _alreadyExistsRegexPattern.IsMatch(result.StandardError) ? new StackAlreadyExistsException(result)
: result.StandardError.IndexOf(_conflictText, StringComparison.Ordinal) >= 0 ? new ConcurrentUpdateException(result)
: result.StandardError.IndexOf(_localBackendConflictText, StringComparison.Ordinal) >= 0 ? new ConcurrentUpdateException(result)
: new CommandException(result);
}
}
4 changes: 3 additions & 1 deletion sdk/go/auto/errors.go
Expand Up @@ -47,7 +47,9 @@ func IsConcurrentUpdateError(e error) bool {
return false
}

return strings.Contains(ae.stderr, "[409] Conflict: Another update is currently in progress.")
conflictText := "[409] Conflict: Another update is currently in progress."
localBackendConflictText := "the stack is currently locked by"
return strings.Contains(ae.stderr, conflictText) || strings.Contains(ae.stderr, localBackendConflictText)
}

// IsSelectStack404Error returns true if the error was a result of selecting a stack that does not exist.
Expand Down
10 changes: 6 additions & 4 deletions sdk/nodejs/automation/errors.ts
Expand Up @@ -62,14 +62,16 @@ export class StackAlreadyExistsError extends CommandError {
const notFoundRegex = new RegExp("no stack named.*found");
const alreadyExistsRegex = new RegExp("stack.*already exists");
const conflictText = "[409] Conflict: Another update is currently in progress.";
const localBackendConflictText = "the stack is currently locked by";

/** @internal */
export function createCommandError(result: CommandResult): CommandError {
const stderr = result.stderr;
return (
notFoundRegex.test(stderr) ? new StackNotFoundError(result) :
alreadyExistsRegex.test(stderr) ? new StackAlreadyExistsError(result) :
stderr.indexOf(conflictText) >= 0 ? new ConcurrentUpdateError(result) :
new CommandError(result)
notFoundRegex.test(stderr) ? new StackNotFoundError(result)
: alreadyExistsRegex.test(stderr) ? new StackAlreadyExistsError(result)
: stderr.indexOf(conflictText) >= 0 ? new ConcurrentUpdateError(result)
: stderr.indexOf(localBackendConflictText) >= 0 ? new ConcurrentUpdateError(result)
: new CommandError(result)
);
}
3 changes: 3 additions & 0 deletions sdk/python/lib/pulumi/automation/errors.py
Expand Up @@ -68,6 +68,7 @@ class InvalidVersionError(Exception):
not_found_regex = re.compile("no stack named.*found")
already_exists_regex = re.compile("stack.*already exists")
conflict_text = "[409] Conflict: Another update is currently in progress."
local_backend_conflict_text = "the stack is currently locked by"
inline_source_error_text = "python inline source runtime error"
runtime_error_regex = re.compile(
"failed with an unhandled exception|panic: runtime error|an unhandled error occurred:"
Expand All @@ -86,6 +87,8 @@ def create_command_error(command_result: "CommandResult") -> CommandError:
return StackAlreadyExistsError(command_result)
if conflict_text in stderr:
return ConcurrentUpdateError(command_result)
if local_backend_conflict_text in stderr:
return ConcurrentUpdateError(command_result)
if compilation_error_regex.search(stdout):
return CompilationError(command_result)
if inline_source_error_text in stdout:
Expand Down