Skip to content

[CosmosDB] Method Item.read() returns undefined instead of throwing error when retrieving item with an invalid ID #27771

Open

Description

Issue

I expected the SDK to throw errors when I retrieve an item by its ID. Instead, I received undefined.

There are other methods from the SDK that throw actual errors when DB operation failed, and having one method that returns undefined confuses me which doesn't help me with keeping a consistent approach for error-handling in my app.

Setup

  • Package Name: @azure/cosmos
  • Package Version: 4.0.0
  • Operating system: W11
  • nodejs
    • version: 18.18.0
  • browser
    • name/version:
  • typescript
    • version: 5.2.2

Describe the bug

When we retrieve item by IDs, we're expecting the SDK to throw an error when no item in the container has been found. Instead, we're receiving undefined as we retrieve item using invalid IDs.

In the source code snippet, it seems that the desired behaviour is to throw errors when error.code !== StatusCodes.NotFound, which means any other errors will be treated as a response to then be returned without throwing errors.

To Reproduce
Steps to reproduce the behavior:

// future-state-role.repository.ts
import { Inject, Service } from 'typedi';
import { ResultAsync, err, ok } from 'neverthrow';

@Service()
export class FutureStateRoleRepository {
  protected className: TRepository = 'FutureStateRoleRepository';

  constructor(
    @Inject() private cosmosService: CosmosService,
  ) {}

  protected get container() {
    const url = env.COSMOS_DB_CONNECTION_STRING;
    const database: Database = 'DatabaseName';
    const container: Container = 'FutureStateRole';
    const cosmosClient = this.cosmosService.createCosmosClient(url);

    if (!cosmosClient) {
      throw new Error('Failed to create CosmosClient!');
    }
    return cosmosClient.database(database).container(container);
  }

  public async findOne(
    args: FutureStateRoleFindUniqueArgs,
  ): Promise<ResultAsync<FutureStateRole, CustomError>> {
    // assume id is 'randomValue` -> which isn't an actual ID
    const { id } = args.where;

    const response = await this.container.item(id, id).read<FutureStateRole>(); // will return 'undefined'
    
    // custom error-handling logic
    if (response.resource === undefined) {
      const errArgs: TCustomError = {
        scope: this.className,
        function: 'findOne',
        message: 'Failed to find FutureStateRole, please provide a valid ID',
      };
      return err(new CustomError(errArgs));
    }
    const serialisedData =
      this.crud.serialiseDateStringsToDateObject<FutureStateRole>(
        response.resource,
      );
    return ok(serialisedData);
  }
}

// cosmos.service.ts
import { Service } from 'typedi';
import { CosmosClient } from '@azure/cosmos';

@Service()
export class CosmosService {
  private cosmosClients: { [connecion: string]: CosmosClient } = {};

  public createCosmosClient(connectionString: string): CosmosClient {
    if (!this.cosmosClients[connectionString]) {
      this.cosmosClients[connectionString] = new CosmosClient(connectionString);
    }
    return this.cosmosClients[connectionString];
  }

  public getCosmosClient(connectionString: string): CosmosClient | undefined {
    return this.cosmosClients[connectionString];
  }
}

Expected behavior
I expected this.container.item(id, id).read() to throw error if id doesn't match any item in the container, instead of receiving undefined

Additional context
If there is a particular reason why returning undefined makes more sense, please let me know.

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

Metadata

Labels

ClientThis issue points to a problem in the data-plane of the library.Cosmoscustomer-reportedIssues that are reported by GitHub users external to the Azure organization.needs-team-attentionWorkflow: This issue needs attention from Azure service team or SDK teamquestionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions