How to debug "Uncaught Error: Trying to use `(==)` on functions"

Hi all,

I wrote a script that handles my http get-requests. While testing (and deliberately creating http-errors, e.g. by disconnecting to the internet) the javascript sometimes crashes and the following error message is in the console:

Uncaught Error: Trying to use `(==)` on functions.
There is no way to know if functions are "the same" in the Elm sense.
Read more about this at https://package.elm-lang.org/packages/elm/core/latest/Basics#== which describes why it is this way and what the better version will look like.
    at _Debug_crash (main.js:753)
    at _Utils_eqHelp (main.js:106)
    at _Utils_eqHelp (main.js:139)
    at _Utils_eqHelp (main.js:139)
    at _Utils_eq (main.js:88)
    at Function.f (main.js:7427)
    at A2 (main.js:56)
    at main.js:8192
    at $author$project$Main$behandelHttpQueue (main.js:8201)
    at Function.f (main.js:12832)
_Debug_crash @ main.js:753
_Utils_eqHelp @ main.js:106
_Utils_eqHelp @ main.js:139
_Utils_eqHelp @ main.js:139
_Utils_eq @ main.js:88
(anonymous) @ main.js:7427
A2 @ main.js:56
(anonymous) @ main.js:8192
$author$project$Main$behandelHttpQueue @ main.js:8201
(anonymous) @ main.js:12832
A2 @ main.js:56
sendToApp @ main.js:1884
(anonymous) @ main.js:1994
_Scheduler_step @ main.js:1810
_Scheduler_enqueue @ main.js:1784
_Scheduler_rawSpawn @ main.js:1715
(anonymous) @ main.js:4585
setInterval (async)
(anonymous) @ main.js:4585
_Scheduler_step @ main.js:1810
_Scheduler_enqueue @ main.js:1784
_Scheduler_rawSpawn @ main.js:1715
handler @ main.js:4124

I cannot find the place where I misuse the (==) operator. Anyone any idea where to find the bug?

Thanks in advance!

Are you able to share the contents of behandelHttpQueue? It looks like that’s where the error is occurring.

Yes, of course. Excuses for my mix of Dutch and English.

behandelHttpQueue : Model -> ( Model, Cmd Msg )
behandelHttpQueue model =
  let
    httpQueueZonderErnstigeFouten = getHttpQueueZonderErnstigeFouten model.httpQueue

    ( newHttpQueue, newInBehandeling, actie ) = 

      case model.httpInBehandeling of

        Just requestInBehandeling -> 
          ( aftellen model.httpQueue
          , model.httpInBehandeling
          , Cmd.none 
          )

        Nothing ->
          if List.isEmpty model.httpQueue then
            vieringenMomentopname model.httpQueue model.vieringenVanServer model.vieringenWerkblad

          else
            case List.head ( List.sortBy .wachttijd httpQueueZonderErnstigeFouten ) of

              Nothing -> 
                ( aftellen model.httpQueue
                , model.httpInBehandeling
                , Cmd.none 
                )

              Just request ->

                if request.wachttijd <= 1 then
                  ( Listx.remove request model.httpQueue
                    |> aftellen
                  , Just request
                  , requestToActie request
                  )
                else
                  ( aftellen model.httpQueue
                  , model.httpInBehandeling
                  , Cmd.none
                  )
  in
    ( { model 
      | httpQueue = newHttpQueue
      , httpInBehandeling = newInBehandeling
      , momentopnameWachttijd = aftellenMomentopname model.momentopnameWachttijd
      }
    , actie )

I’m guessing this is the issue. You are removing this item from the list based on if it equals any of the items in the list. But model.httpQueue probably contains functions that you can’t do equality testing on.

Thanks for the suggestion @MartinS
I tried to avoid the problem by not putting encoded json in this list, but I might overlook something.

The relevant types here are:

type alias Model =
  { httpQueue : List HttpRequest
  ... }

type alias HttpRequest =
  { requestData : RequestData
  , expect : Http.Expect Msg
  , poging : Int
  , wachttijd : Int
  , omschrijving : String
  , foutmelding : Maybe Http.Error
  }

type RequestData
  = FetchAllLocaties
  | FetchAllVoorgangers
  | FetchAllVieringen
  | SaveAllLocaties ( List Locatie )
  | SaveVoorgangerRequest Voorganger
  | SaveNieuweViering Viering
  | VerwerkMomentopname ( List Int ) ( List Viering )
  | DeleteViering Int
  | UpdateViering Viering

Do you see something that could cause the error?

Http.Expect is a function that takes the response of the http request and converts it into a Msg so it isn’t equatable. What I recommend is that you have some id that you can store in httpQueue instead and use to reference the HttpRequest data.

2 Likes

Thanks a lot @MartinS
I didn’t realize that Http.Expect was a function, but I could have guessed it.

My solution is to remove the expect from the type alias HttpRequest. The type RequestData implies both the json-encoding and the expected response. When building the http command, I can get these based on the RequestData.

1 Like

Wanted to wait till you found the solution to mention that you can shorten you case List.head ( List.sortBy .wachttijd section of code to

case List.sortBy .wachttijd httpQueueZonderErnstigeFouten of
    [] -> -- empty case
    request :: _ -> -- extract the head case
3 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.