Optional dependency in library generates `undefined` warnings in client application

I have this little helper library that specifies an optional dependency on :jose. In the library code, some modules use :jose functions, for example JOSE.JWT.peek_payload/1. I’m not using any of those modules in my client application that uses the library.

During compilation of my client application, I get the following output when the library is compiled:

==> my_incredible_library
Compiling 11 files (.ex)
warning: function JOSE.JWK.from/1 is undefined (module JOSE.JWK is not available)
  lib/security/oauth2_plug.ex:115

warning: function JOSE.JWS.compact/1 is undefined (module JOSE.JWS is not available)
  lib/test_helpers.ex:90

etc etc

Is there a way to suppress those warnings in client applications from the library code? Or do I misunderstand optional dependencies and should :jose be a non-optional dependency in this case?

I may be mistaken, but I believe that this should be opened as an issue on the library: it shouldn’t consider calls to optional dependencies if they are not present. See for example https://github.com/davidsulc/scrapy_cloud_ex/blob/master/lib/http_adapters/default.ex#L1

I’m the author of the library as well so I’m quite confident that the eventual solution will be implemented in it :stuck_out_tongue: It’s still under development, it’s more of an alpha-versions situation.

So you’re saying that either the dependency should not be marked optional OR I should disable the entire modules / functions that depend on that dependency using Code.ensure_loaded?/1? Is that a valid way to go about it? That would cause the docs to state that a module exists while in reality it does not if that dependency is not present. Is that a standard library design in Elixir?

1 Like

What I’m saying is that if the dependency truly is optional, then the library should work perfectly if that dependency isn’t present. In other words, optional dependencies don’t mean “it will work without this dependency provided you have call those functions over there”.

Public functionality (that would be exposed in docs) should always work, even if the optional dependencies aren’t there, so you shouldn’t run into the case where documentation is missing because optional dependencies aren’t present.

If a dependency is optional, it should only add “nice to have” things in your library. In ecto https://github.com/elixir-ecto/ecto/blob/master/lib/ecto/json.ex#L1 they add protocol implementations if the optional Jason depency is present. In a library I wrote (which may therefore be incorrect, take with grain of salt, caveat emptor, etc.), a default implementation is compiled if the corresponding optional dependency is found: https://github.com/davidsulc/scrapy_cloud_ex/blob/master/lib/http_adapters/default.ex#L1

Hope this helps!

Yes. Example: https://github.com/absinthe-graphql/absinthe_relay/blob/a821a22f127b4fd81d2195372739c47ed8c45829/lib/absinthe/relay/connection.ex#L441