elixir-mongodb-driver icon indicating copy to clipboard operation
elixir-mongodb-driver copied to clipboard

Dialyzer/Type Check errors

Open PragTob opened this issue 4 months ago • 2 comments

👋

Hi there me again, and thanks again!

Problem

When doing use Mongo.Repo dialyzer spits out type errors, specifically for update_all/4 (so they do not happen when used with read_only: true).

The emitted errors
lib/mongo/repo.ex:2:pattern_match
The pattern can never match the type.

Pattern:
{:ok, %{:inserted_ids => _}}

Type:

  {:error,
   %{
     :__exception__ => true,
     :__struct__ => Mongo.Error | Mongo.WriteError,
     :code => number(),
     :error_info => map(),
     :error_labels => nil | [binary()],
     :fail_command => boolean(),
     :host => binary(),
     :message => binary(),
     :n => number(),
     :not_writable_primary_or_recovering => boolean(),
     :ok => number(),
     :resumable => boolean(),
     :retryable_reads => boolean(),
     :retryable_writes => boolean(),
     :write_errors => [map()]
   }}


________________________________________________________________________________
lib/mongo/repo.ex:2:callback_type_mismatch
Type mismatch for @callback update_all/4 in Mongo.Repo behaviour.

Expected type:

  {:ok,
   {:error,
    %{
      :__exception__ => true,
      :__struct__ => Mongo.Error | Mongo.WriteError,
      :code => number(),
      :error_info => map(),
      :error_labels => nil | [binary()],
      :fail_command => boolean(),
      :host => binary(),
      :message => binary(),
      :n => number(),
      :not_writable_primary_or_recovering => boolean(),
      :ok => number(),
      :resumable => boolean(),
      :retryable_reads => boolean(),
      :retryable_writes => boolean(),
      :write_errors => [map()]
    }}
   | {:ok,
      %Mongo.UpdateResult{
        :acknowledged => boolean(),
        :matched_count => non_neg_integer(),
        :modified_count => non_neg_integer(),
        :upserted_ids => [%BSON.ObjectId{:value => <<_::96>>}]
      }}}


Actual type:

  {:error,
   %{
     :__exception__ => true,
     :__struct__ => Mongo.Error | Mongo.WriteError,
     :code => number(),
     :error_info => map(),
     :error_labels => nil | [binary()],
     :fail_command => boolean(),
     :host => binary(),
     :message => binary(),
     :n => number(),
     :not_writable_primary_or_recovering => boolean(),
     :ok => number(),
     :resumable => boolean(),
     :retryable_reads => boolean(),
     :retryable_writes => boolean(),
     :write_errors => [map()]
   }}
  | {:ok,
     %Mongo.UpdateResult{
       :acknowledged => boolean(),
       :matched_count => non_neg_integer(),
       :modified_count => non_neg_integer(),
       :upserted_ids => [map()]
     }}

Solution

The best solution would probably be to run dialyxir/dialyzer locally in the repo and fix the type issues.

I'd understand though if you wouldn't wanna take that on you :) I can help with basic dialyzer setup if needed. (I'd just copy it from benchee which works well enough).

Workaround

For anyone else that comes, I surpressed the warnings via @dialyzer [:no_match, :no_return, :no_behaviours]. That said, while I don't love dialyzer the errors mildly worry me but I don't use update_all at least so far :)

PragTob avatar Sep 16 '25 09:09 PragTob

Image

PragTob avatar Sep 16 '25 09:09 PragTob

Thank you for the detailed issue description.

The best solution would probably be to run dialyxir/dialyzer locally in the repo and fix the type issues.

Yeah...As you correctly guessed, type specifications and dialyzers are not exactly my strong suit in this project. When I have some time I will follow your suggestion and try to fix the warnings.

zookzook avatar Sep 17 '25 13:09 zookzook

And it will take some time...

zookzook avatar Dec 14 '25 18:12 zookzook