Awesome job on the PR!

On Fri, May 15, 2020 at 23:09 Dallin Osmun <dos...@gmail.com> wrote:

> Hi José
>
> Thank you so much for taking the time to respond to this thread. It has
> been incredibly helpful and is very much appreciated!
>
> I think I may have found an issue with how line numbers are determined for
> exceptions raised in macros. I submitted a PR here:
> https://github.com/elixir-lang/elixir/pull/10040
>
>
> On Friday, May 15, 2020 at 2:29:48 PM UTC-6, José Valim wrote:
>>
>> Given Elixir compile time is really executing code, then I think it would
>> be a nice feature to attempt to extract it from exceptions, although I
>> understand it can be brittle.
>>
>> If the error is really a compile-time reason (invalid syntax, invalid
>> call, etc), then Elixir does show a proper error with file:line.
>>
>> On Fri, May 15, 2020 at 9:30 PM cward <cade...@gmail.com> wrote:
>>
>>> It seems unreasonable for the editor to infer the line number from the
>>> `message` key. Am I wrong in thinking that? It seems that `position` is
>>> getting lost at some point in translation. Why would the `message` string
>>> contain the full stacktrace with line number, but `position` is `nil`?
>>>
>>> After reading this thread, I now realize that this is actually somewhat
>>> common. I don't have a use case off the top of my head, but it's often that
>>> the `position` key is lost when an error comes from a macro.
>>>
>>> In the case of elixir_ls (vscode language server), the position is
>>> expected, and the fallback is to highlight the whole file:
>>> https://github.com/elixir-lsp/elixir-ls/blob/master/apps/language_server/lib/language_server/build.ex#L63
>>>
>>> On Friday, May 15, 2020 at 12:30:52 PM UTC-6, José Valim wrote:
>>>>
>>>> You can use reraise/3. It is a bit misnamed, but it is correct. But
>>>> this behaviour in particular sounds like a bug in the editor itself, given
>>>> it does have a line in the stacktrace specific to that file.
>>>>
>>>> On Fri, May 15, 2020 at 8:04 PM Dallin Osmun <dos...@gmail.com> wrote:
>>>>
>>>>> I must be missing something. I am already using Macro.Env.stacktrace
>>>>> when emitting my warnings and that's working great. The problem happens
>>>>> when calling raise. Is there a way to pass a new stacktrace into raise? 
>>>>> The
>>>>> docs for Kernel.raise say it accepts either a message or an exception and
>>>>> attributes. Kernel.reraise takes in a stacktrace but when I use that I 
>>>>> only
>>>>> see changes in the compiler diagnostic's message; not in it's file nor
>>>>> position.
>>>>>
>>>>>
>>>>> On Friday, May 15, 2020 at 11:45:10 AM UTC-6, José Valim wrote:
>>>>>>
>>>>>> 1. Yes, the granularity you get is per macro.
>>>>>>
>>>>>> 2. When emitting the warning, do "Macro.Env.stacktrace(__CALLER__)"
>>>>>> to get the actual caller. You may also need to look at the AST to get the
>>>>>> proper line. Note you would need to do the same if we were to introduce
>>>>>> some sort of IO.error.
>>>>>>
>>>>>> On Fri, May 15, 2020 at 6:22 PM Dallin Osmun <dos...@gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> Hi José,
>>>>>>>
>>>>>>> Thanks for the helpful response!
>>>>>>>
>>>>>>> What you are saying makes sense. I must admit I don't have a very
>>>>>>> advanced knowledge of metaprogramming in elixir so I'll have to
>>>>>>> learn/practice a lot more before I can come up with an informed 
>>>>>>> response.
>>>>>>>
>>>>>>> I tried out your suggestion and wanted to report back on how it
>>>>>>> went. Using IO.warn to report problems worked well. However, two issues
>>>>>>> arose when I added this line to the end of the macro:
>>>>>>>
>>>>>>> raise "There are errors in your query"
>>>>>>>
>>>>>>>
>>>>>>> Here is the code in question:
>>>>>>>
>>>>>>>
>>>>>>> defmodule Queries do
>>>>>>>   use MyGoblet
>>>>>>>
>>>>>>>   query "First" do
>>>>>>>     error1
>>>>>>>     error2
>>>>>>>   end
>>>>>>>
>>>>>>>   query "Second" do
>>>>>>>     error3
>>>>>>>     error4
>>>>>>>   end
>>>>>>> end
>>>>>>>
>>>>>>>
>>>>>>> 1. The first call to the macro ran, reported warnings, and then
>>>>>>> raised, halting compilation. error3 and error4 were then never reported.
>>>>>>> This can be resolved by calling raise in an @after_compile hook but I 
>>>>>>> fear
>>>>>>> doing so may suffer from the same issues you described above. Unless you
>>>>>>> have any other suggestions I think that this issue, while not ideal, is
>>>>>>> still acceptable.
>>>>>>>
>>>>>>> 2. Calling raise inside the macro caused the entire file in my
>>>>>>> editor to turn red which made it next-to-impossible to see the original
>>>>>>> warnings (see the attached screenshot). This was the diagnostic that was
>>>>>>> reported from elixir:
>>>>>>>
>>>>>>>
>>>>>>> %Mix.Task.Compiler.Diagnostic{
>>>>>>>   compiler_name: "Elixir",
>>>>>>>   details: nil,
>>>>>>>   file: "/Users/dallin/code/goblet/lib/testing.ex",
>>>>>>>   message: "** (RuntimeError) There are errors in your query\n
>>>>>>> (goblet 0.1.0) lib/goblet.ex:74: Goblet.build/6\n    expanding macro:
>>>>>>> MyGoblet.query/2\n    lib/testing.ex:8: Queries (module)\n",
>>>>>>>   position: nil,
>>>>>>>   severity: :error
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> Even though the stack trace has a line number in it, that position
>>>>>>> is missing at the root of the diagnostic. This is what ultimately causes
>>>>>>> the issue. Would you like me to file this as a bug in the elixir issue
>>>>>>> tracker? Or should I instead work with the authors of the editor plugin 
>>>>>>> to
>>>>>>> handle position-less Diagnostics differently?
>>>>>>>
>>>>>>> [image: screenshot.png]
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Wednesday, May 13, 2020 at 12:20:29 PM UTC-6, José Valim wrote:
>>>>>>>>
>>>>>>>> Hi Dallin,
>>>>>>>>
>>>>>>>> Thank you for the detailed proposal.
>>>>>>>>
>>>>>>>> It is important to remember that in Elixir compilation and
>>>>>>>> execution steps are not necessarily distinct. For example, someone 
>>>>>>>> could
>>>>>>>> have this project:
>>>>>>>>
>>>>>>>> # lib/a.ex
>>>>>>>> defmodule A do
>>>>>>>>   use UsesYourMacro
>>>>>>>>   query do
>>>>>>>>     ...
>>>>>>>>   end
>>>>>>>> end
>>>>>>>>
>>>>>>>> # lib/b.ex
>>>>>>>> defmodule B do
>>>>>>>>   A.query
>>>>>>>> end
>>>>>>>>
>>>>>>>> In other words, B can already try to execute the code from A before
>>>>>>>> compilation finishes. Therefore, "error" can be misleading because
>>>>>>>> continuing compilation with an error can lead to cascading failures, 
>>>>>>>> and
>>>>>>>> causing the user to chase a bug that's not the original one.
>>>>>>>>
>>>>>>>> At best, you would need to consider mixing "IO.error" and "raise".
>>>>>>>> My suggestion in your case is to emit warnings for all errors in a
>>>>>>>> particular query definition, allowing the user to get multiple 
>>>>>>>> reports, and
>>>>>>>> then raise at the end of that query definition if any warning was 
>>>>>>>> emitted.
>>>>>>>>
>>>>>>>> This doesn't provide warnings across all files but it can be a good
>>>>>>>> starting point, especially because we indeed cannot continue beyond 
>>>>>>>> that
>>>>>>>> file for the reasons I mentioned above.
>>>>>>>>
>>>>>>>>
>>>>>>> --
>>>>>>> You received this message because you are subscribed to the Google
>>>>>>> Groups "elixir-lang-core" group.
>>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>>> send an email to elixir-l...@googlegroups.com.
>>>>>>> To view this discussion on the web visit
>>>>>>> https://groups.google.com/d/msgid/elixir-lang-core/ad4e81d8-6495-4511-ad7b-f6064dd1a95c%40googlegroups.com
>>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/ad4e81d8-6495-4511-ad7b-f6064dd1a95c%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>>> .
>>>>>>>
>>>>>> --
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "elixir-lang-core" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>>> an email to elixir-l...@googlegroups.com.
>>>>> To view this discussion on the web visit
>>>>> https://groups.google.com/d/msgid/elixir-lang-core/704b0050-1e98-4322-b63f-34ebdc36e324%40googlegroups.com
>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/704b0050-1e98-4322-b63f-34ebdc36e324%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>
>>>>
>>>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "elixir-lang-core" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to elixir-l...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/elixir-lang-core/d92d2a86-2b27-406f-9d70-a96600fc51ed%40googlegroups.com
>>> <https://groups.google.com/d/msgid/elixir-lang-core/d92d2a86-2b27-406f-9d70-a96600fc51ed%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to elixir-lang-core+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/92e66d66-8ab6-44e1-a69c-33a82b88d791%40googlegroups.com
> <https://groups.google.com/d/msgid/elixir-lang-core/92e66d66-8ab6-44e1-a69c-33a82b88d791%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4K440wNvAJkorZN5CmifvBaVNaLk6bJQMVt3WiU3tndLQ%40mail.gmail.com.

Reply via email to