Skip to content

DynamoDB does not return TableAlreadyExistsException when CreateTable is called for an existing table name #2487

Closed as not planned
@tep

Description

Describe the bug

If (*dynamodb.Client).CreateTable(...) is called using a table name that already exists, the returned error should be of type types.TableAlreadyExistsException and not types.ResourcesInUseException.

Expected Behavior

The returned error should be of type types.TableAlreadyExistsException.

Current Behavior

The returned error is of type types.ResourceInUseException along with a message mentioning "Table already exists"

Reproduction Steps

package main

import (
  "context"
  "errors"
  "fmt"
  "os"
  "time"

  "github.com/aws/aws-sdk-go-v2/aws"
  "github.com/aws/aws-sdk-go-v2/config"
  "github.com/aws/aws-sdk-go-v2/service/dynamodb"
  "github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)

func main() {
  ctx := context.Background()
  if err := run(ctx); err != nil {
    fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
  }
}

func run(ctx context.Context) error {
  cfg, err := config.LoadDefaultConfig(ctx)
  if err != nil {
    return err 
  }

  return CreateTable(ctx, cfg, "NEW_TABLE")
}

func CreateTable(ctx context.Context, cfg aws.Config, tableName string) error {
  ddb := dynamodb.NewFromConfig(cfg)

  input := &dynamodb.CreateTableInput{
    TableName: aws.String(tableName),
    AttributeDefinitions: []types.AttributeDefinition{
      {AttributeName: aws.String("ATTR1"), AttributeType: types.ScalarAttributeTypeS},
      {AttributeName: aws.String("ATTR2"), AttributeType: types.ScalarAttributeTypeS},
    },  
    KeySchema: []types.KeySchemaElement{
      {AttributeName: aws.String("ATTR1"), KeyType: types.KeyTypeHash},
      {AttributeName: aws.String("ATTR2"), KeyType: types.KeyTypeRange},
    },  
    ProvisionedThroughput: &types.ProvisionedThroughput{
      ReadCapacityUnits:  aws.Int64(1),
      WriteCapacityUnits: aws.Int64(1),
    },  
  }

  // Create table
  if _, err := ddb.CreateTable(ctx, input); err != nil {
    return err 
  }

  fmt.Printf("Table %q created successfully: pausing 10s\n", tableName)

  time.Sleep(10 * time.Second)

  fmt.Println("Will attempt again\n")

  // Attempt to create same table again
  if _, err := ddb.CreateTable(ctx, input); err != nil {
    taex := new(types.TableAlreadyExistsException)
    if errors.As(err, &taex) { // XXX <<--- This is false...
      fmt.Println("TABLE EXISTS (as it should")
      return nil 
    }   

    riux := new(types.ResourceInUseException)
    if errors.As(err, &riux) { // XXX <<--- ...while this is true.
      fmt.Printf("Resource in Use: code=%q message=%q\n", riux.ErrorCode(), riux.ErrorMessage())
      return nil 
    }   

    return fmt.Errorf("some other error: %w", err)
  }

  return nil // We never get here.
}

Possible Solution

Given that the string "Table already exists" does not exist in the source code for DynamoDB Go module, I suspect this error is being incorrectly generated on the server side.

Additional Information/Context

The Go authors strongly discourage the practice of parsing error messages in order to distinguish one error from another and instead recommend that this determination be based on a properly typed value.

Since the DynamoDB modules contains the TableAlreadyExistsException it should be used in this situation.

AWS Go SDK V2 Module Versions Used

github.com/aws/[email protected] github.com/aws/[email protected]
github.com/aws/[email protected] github.com/google/[email protected]
github.com/aws/[email protected] github.com/jmespath/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/feature/ec2/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/internal/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/service/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/service/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/service/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/google/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/internal/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/internal/endpoints/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/service/internal/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/service/internal/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/feature/ec2/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/service/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/service/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/service/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/google/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/internal/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/internal/endpoints/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/service/internal/[email protected]
github.com/aws/aws-sdk-go-v2/[email protected] github.com/aws/aws-sdk-go-v2/service/internal/[email protected]
github.com/aws/aws-sdk-go-v2/feature/dynamodb/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/feature/dynamodb/[email protected] github.com/aws/aws-sdk-go-v2/service/[email protected]
github.com/aws/aws-sdk-go-v2/feature/dynamodb/[email protected] github.com/aws/aws-sdk-go-v2/service/[email protected]
github.com/aws/aws-sdk-go-v2/feature/dynamodb/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/feature/dynamodb/[email protected] github.com/google/[email protected]
github.com/aws/aws-sdk-go-v2/feature/dynamodb/[email protected] github.com/jmespath/[email protected]
github.com/aws/aws-sdk-go-v2/feature/ec2/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/feature/ec2/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/feature/ec2/[email protected] github.com/google/[email protected]
github.com/aws/aws-sdk-go-v2/internal/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/internal/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/internal/endpoints/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/internal/endpoints/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/internal/endpoints/[email protected] github.com/google/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/aws-sdk-go-v2/internal/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/aws-sdk-go-v2/internal/endpoints/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/aws-sdk-go-v2/service/internal/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/aws-sdk-go-v2/service/internal/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/google/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/jmespath/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/aws-sdk-go-v2/internal/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/aws-sdk-go-v2/internal/endpoints/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/google/[email protected]
github.com/aws/aws-sdk-go-v2/service/internal/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/internal/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/internal/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/internal/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/internal/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/internal/[email protected] github.com/google/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/aws-sdk-go-v2/internal/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/aws-sdk-go-v2/internal/endpoints/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/google/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/aws-sdk-go-v2/internal/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/aws-sdk-go-v2/internal/endpoints/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/google/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/aws-sdk-go-v2/internal/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/aws-sdk-go-v2/internal/endpoints/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/aws-sdk-go-v2/service/internal/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/aws-sdk-go-v2/service/internal/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/[email protected] github.com/google/[email protected]
github.com/aws/[email protected] github.com/google/[email protected]

Compiler and Version used

go version go1.21.6 linux/amd64

Operating System and version

$ uname -a
Linux ptolemy.toolman.org 5.4.0-164-generic #181-Ubuntu SMP Fri Sep 1 13:41:22 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

bugThis issue is a bug.service-apiThis issue is due to a problem in a service API, not the SDK implementation.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions