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

Cryptic error message #48

Open
eKristensen opened this issue Nov 7, 2023 · 3 comments
Open

Cryptic error message #48

eKristensen opened this issue Nov 7, 2023 · 3 comments

Comments

@eKristensen
Copy link

Hi

I have medium sized project that I used to check potential edge-cases in Eqwalizer. I've discovered a very cryptic error message when certain conditions are met. One of them is that the module name does not match the file name.

I got a file app_a/src/app_a.erl that starts with -module(app_y). which is obviously wrong.

If I use erlang or dialyzer I get a nice error message saying what's wrong:

Here Erlang:

[ek@ek-xps demo01]$ erl -compile app_a/src/app_a.erl
app_a.beam: Module name 'app_y' does not match file name 'app_a'

Dialyzer:

[ek@ek-xps demo01]$ rebar3 dialyzer
===> Analyzing applications...
===> Compiling eqwalizer_rebar3
===> Verifying dependencies...
===> Analyzing applications...
===> Compiling app_a
===> Compiling app_a/src/app_a.erl failed
_build/default/lib/app_a/ebin/app_a.beam:none: Module name 'app_y' does not match file name 'app_a'

However with eqwalizer I get this cryptic message:

[ek@ek-xps demo01]$ elp eqwalize app_a
Loading rebar3 build_info                                                                                             
Loading applications      ████████████████████ 5/5                                                                    
Seeding database                                                                                                      
Compiling dependencies                                                                                                
eqWAlizing                ░░░░░░░░░░░░░░░░░░░░ 0/1  app_a                                                           
Exception in thread "main" java.util.NoSuchElementException: None.get
    at scala.None$.get(Option.scala:627)
    at scala.None$.get(Option.scala:626)
    at com.whatsapp.eqwalizer.tc.Util.globalFunId(Util.scala:21)
    at com.whatsapp.eqwalizer.tc.Elab.elabExpr(Elab.scala:129)
    at com.whatsapp.eqwalizer.tc.Check.checkExpr(Check.scala:134)
    at com.whatsapp.eqwalizer.tc.Check.checkBody(Check.scala:67)
    at com.whatsapp.eqwalizer.tc.Check.checkClause(Check.scala:109)
    at com.whatsapp.eqwalizer.tc.Check.$anonfun$checkFun$1(Check.scala:38)
    at scala.collection.LazyZip2$$anon$1$$anon$2.next(LazyZipOps.scala:42)
    at scala.collection.immutable.List.prependedAll(List.scala:153)
    at scala.collection.immutable.List$.from(List.scala:684)
    at scala.collection.immutable.List$.from(List.scala:681)
    at scala.collection.BuildFromLowPriority2$$anon$11.fromSpecific(BuildFrom.scala:112)
    at scala.collection.BuildFromLowPriority2$$anon$11.fromSpecific(BuildFrom.scala:109)
    at scala.collection.LazyZip2.map(LazyZipOps.scala:37)
    at com.whatsapp.eqwalizer.tc.Check.checkFun(Check.scala:38)
    at com.whatsapp.eqwalizer.Pipeline$.tolerantCheckFun(Pipeline.scala:111)
    at com.whatsapp.eqwalizer.Pipeline$.checkFun(Pipeline.scala:91)
    at com.whatsapp.eqwalizer.Pipeline$.$anonfun$checkForms$1(Pipeline.scala:52)
    at scala.collection.immutable.List.foreach(List.scala:333)
    at com.whatsapp.eqwalizer.Pipeline$.checkForms(Pipeline.scala:35)
    at com.whatsapp.eqwalizer.util.ELPDiagnostics$.getDiagnostics(ELPDiagnostics.scala:64)
    at com.whatsapp.eqwalizer.util.ELPDiagnostics$.$anonfun$getDiagnosticsIpc$2(ELPDiagnostics.scala:36)
    at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:563)
    at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:561)
    at scala.collection.AbstractIterable.foreach(Iterable.scala:926)
    at scala.collection.IterableOps$WithFilter.foreach(Iterable.scala:896)
    at com.whatsapp.eqwalizer.util.ELPDiagnostics$.getDiagnosticsIpc(ELPDiagnostics.scala:34)
    at com.whatsapp.eqwalizer.Main$.ipc(Main.scala:65)
    at com.whatsapp.eqwalizer.Main$.main(Main.scala:29)
    at com.whatsapp.eqwalizer.Main.main(Main.scala)
thread 'main' panicked at crates/eqwalizer/src/ipc.rs:91:40:
failed to parse stdout from eqwalizer: Error("EOF while parsing a value", line: 1, column: 0)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Version info: elp 0.17.16 (or at least that is what it says, see #47 )

I have tried to determine what goes wrong and have determined that the parse error relate to some IPC. The mini-elp requests that eqwalizer should do something, and it fails - most likely to parse the app_a.erl. Mini-elp does not know how to parse a java error message, therefore the code fails with a parse error.

To debug further I have tried to run strace -f, but I get a lot of data (1.5+ million lines of logs) which is not easy for me to filter since I have only very limited knowledge of both eqwalizer and erlang. I have tried to search the source code, but I've not been able to determine where the error originate from. I'm not even sure in which file the fault lies, since it looks like the fault is carried along from somewhere else...

I think the root of the issue has to do with how the .erl files are parsed, however that may happen. I suppose Erlang is used (maybe erl -compile ?), but again I'm not sure where to find the initialization of the parsing process. I have some vague guesses, but I want to avoid making this issue report too long. Eqwalizer and/or mini-elp must do at least some parsing on it's own since it is checking the content of comments.

TL;DR: I would argue a simple parse error should make the application blow up like it is doing right now.

I would be happy to help in whatever way I can to resolve this issue. If I can learn more about how eqwalizer works in the process then it would be fantastic.

Thank you in advance.

@eKristensen
Copy link
Author

A minor update: The issue persists in d61310a

@VLanvin
Copy link
Contributor

VLanvin commented Nov 8, 2023

Hi, thanks for the report.

Yes, we indeed do not check that the module annotation matches the name of the file in eqWAlizer. We usually run eqWAlizer alongside Dialyzer, meaning this would be caught properly by Dialyzer.

Nevertheless, such a check would be a nice addition. I think the best place to add it would be right into mini-elp, probably in the parse server so that checking fails properly before eqWAlizer even runs.

@eKristensen
Copy link
Author

Nevertheless, such a check would be a nice addition. I think the best place to add it would be right into mini-elp, probably in the parse server so that checking fails properly before eqWAlizer even runs.

I have already looked at that folder. It is nice to get a confirmation that I was looking at the right place.

I'm struggling to start the parser on it's own. If i run rebar3 shell from the parse server folder I get a shell where I can call the parse server functions, but I'm not sure which function to call to parse a file. Am I on the right track?

I have tried to look for documentation, this repo mainly has documentation related to how to use eqwalizer and design choices, not much about the architecture of the code-base itself.

There is obviously a relation to https://github.com/WhatsApp/erlang-language-platform - but I am not sure where mini-elp and elp differs...

If I'm understanding it correctly the parse server is more or less a copy of the parser from the official Erlang source code that has been adjusted to the needs you have. But it still seems to be using erlang? I'm not sure where what happens
I have found this: https://github.com/WhatsApp/erlang-language-platform/blob/main/docs/ELP-parser-dataflow.png which is properly the closest to a description of the dataflow that I've found so far.

Thank you for your time.

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

2 participants