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

get item by partition key returns error only inside lambda #412

Open
orr-levinger opened this issue Nov 8, 2023 · 0 comments
Open

get item by partition key returns error only inside lambda #412

orr-levinger opened this issue Nov 8, 2023 · 0 comments

Comments

@orr-levinger
Copy link

orr-levinger commented Nov 8, 2023

Describe the bug
This bug happens to me only when running in a lambda. When running locally this doesnt happen.
here are my libs versions:

dynamo-easy version: 8.0.0-next.3
aws v3 dynamo version: 3.445.0
Node.js Version: v18.18.0

I have a model that has a string field called status:

import {
  Model,
  PartitionKey,
  SortKey,
  LSISortKey,
  GSIPartitionKey,
  GSISortKey,
  Property,
  fromDb as fromDBB,
  PropertyMetadata,
  metadataForModel,
  Attributes,
  ModelConstructor,
} from '@shiftcoders/dynamo-easy';
import { BaseDynamoModel } from '@models/base-dynamo-model';
import { MATCH_TABLE } from '@static/consts';
import { MatchGraphQLType, Quality, RejectReason } from '@type/Match';
import type { MatchStatus } from '@type/Match';
import { Avatar, Gender } from '@type/User';
import type { MapperForType, StringAttribute } from '@shiftcoders/dynamo-easy';


@Model({ tableName: MATCH_TABLE })
export class MatchModel extends BaseDynamoModel implements MatchGraphQLType {
  static readonly byUniqueId = 'byUniqueId';
  static readonly byMatchIdUserId = 'byMatchId-userId';
  static readonly byUserIdStatus = 'byUserId-status';
  static readonly byUserIdActive = 'byUserId-active';
  static readonly byConversationId = 'byConversationId';
  @GSIPartitionKey(MatchModel.byUniqueId)
  id: string;
  @PartitionKey()
  @GSISortKey(MatchModel.byMatchIdUserId)
  userId: string;
  @SortKey()
  @GSIPartitionKey(MatchModel.byMatchIdUserId)
  matchId: string;

  @LSISortKey(MatchModel.byUserIdStatus)
  @Property({ mapper: statusMapper })
  **status: MatchStatus;**

  @LSISortKey(MatchModel.byUserIdActive)
  active: 'true' | 'false';
}

export type MatchStatus =
  | 'pending'
  | 'invited'
  | 'accepted'
  | 'failure'
  | 'success';

here is the DDB table definition:

  MatchesTable:
    DeletionPolicy: Delete
    Type: "AWS::DynamoDB::Table"
    Properties:
      Tags:
        - Key: env
          Value: ${sls:stage}
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
        - AttributeName: status
          AttributeType: S
        - AttributeName: userId
          AttributeType: S
        - AttributeName: matchId
          AttributeType: S
        - AttributeName: active
          AttributeType: S
      KeySchema:
        - AttributeName: userId
          KeyType: HASH
        - AttributeName: matchId
          KeyType: RANGE
      LocalSecondaryIndexes:
        - IndexName: byUserId-status
          KeySchema:
            - AttributeName: userId
              KeyType: HASH
            - AttributeName: status
              KeyType: RANGE
          Projection:
            ProjectionType: ALL
        - IndexName: byUserId-active
          KeySchema:
            - AttributeName: userId
              KeyType: HASH
            - AttributeName: active
              KeyType: RANGE
          Projection:
            ProjectionType: ALL
      GlobalSecondaryIndexes:
        - IndexName: byUniqueId
          KeySchema:
            - AttributeName: id
              KeyType: HASH
          Projection:
            ProjectionType: ALL
        - IndexName: byMatchId-userId
          KeySchema:
            - AttributeName: matchId
              KeyType: HASH
            - AttributeName: userId
              KeyType: RANGE
          Projection:
            ProjectionType: ALL
      BillingMode: PAY_PER_REQUEST
      TableName: ${self:custom.base}-matches
      StreamSpecification:
        StreamViewType: NEW_AND_OLD_IMAGES

here is my table item instance:

  "userId": {
    "S": "f43276be-3a2c-4888-b2b9-9ae23471094c"
  },
  "matchId": {
    "S": "4913f5ad-198e-4fcd-b929-2f3e996ce6ce"
  },
  "active": {
    "S": "true"
  },
  "id": {
    "S": "f43276be-3a2c-4888-b2b9-9ae23471094c_4913f5ad-198e-4fcd-b929-2f3e996ce6ce"
  },
  "status": {
    "S": "invited"
  }
}

this is the query i run:

  async getMatchById(id: string) {
    return this.query().index(MatchModel.byUniqueId).wherePartitionKey(id).execSingle();
  }

only when this code runs inside lambda i get the error:
{
"errorType": "Error",
"errorMessage": "could not resolve the dynamo db type for attribute value invited",
"stack": [
"Error: could not resolve the dynamo db type for attribute value invited",
" at typeOfFromDb (/opt/nodejs/node_modules/@shiftcoders/dynamo-easy/src/mapper/util.ts:231:9)",
" at fromDbOne (/opt/nodejs/node_modules/@shiftcoders/dynamo-easy/src/mapper/mapper.ts:291:64)",
" at /opt/nodejs/node_modules/@shiftcoders/dynamo-easy/src/mapper/mapper.ts:274:20",
" at Array.forEach ()",
" at fromDb (/opt/nodejs/node_modules/@shiftcoders/dynamo-easy/src/mapper/mapper.ts:244:44)",
" at Object.fromDb (/var/task/src/functions/events/webpack:/blind-chat-backend/src/models/match-model.ts:75:14)",
" at /opt/nodejs/node_modules/@shiftcoders/dynamo-easy/src/mapper/mapper.ts:268:50",
" at Array.forEach ()",
" at fromDb (/opt/nodejs/node_modules/@shiftcoders/dynamo-easy/src/mapper/mapper.ts:244:44)",
" at /opt/nodejs/node_modules/@shiftcoders/dynamo-easy/src/dynamo/request/read-many.request.ts:222:63",
" at Array.map ()",
" at ReadManyRequest.mapFromDb (/opt/nodejs/node_modules/@shiftcoders/dynamo-easy/src/dynamo/request/read-many.request.ts:222:43)",
" at processTicksAndRejections (node:internal/process/task_queues:95:5)",
" at Runtime.v [as handler] (/var/task/src/functions/events/webpack:/blind-chat-backend/src/functions/events/get-match.ts:16:3)"
]
}

when creating a property mapper:

export const statusMapper: MapperForType<string, StringAttribute> = {
  fromDb: (attributeValue: any): any => {
    console.log('fromDb orr', attributeValue);
    return attributeValue.S;
  },
  toDb: (modelValue: any): any => {
    console.log('toDb orr', modelValue);
    try {
      return modelValue;
    } catch (e) {
      console.log('error', e);
      return modelValue;
    }
  },
};

that does nothing special just what dynamo-easy was supposed to do it works..
and prints:
fromDb orr { S: 'invited' }

also noticed the wrong mapper is chosen:
INFO dynamo.mapper.mapper (Object): map toDb {"item":"Conscientiousness"}

image

@orr-levinger orr-levinger changed the title git i item by partition key returns error git get item by partition key returns error Nov 8, 2023
@orr-levinger orr-levinger changed the title git get item by partition key returns error get item by partition key returns error Nov 8, 2023
@orr-levinger orr-levinger changed the title get item by partition key returns error get item by partition key returns error only inside lambda Nov 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant