Re: [elixir-core:9490] Re: Proposal: IO.error/2
Awesome job on the PR! On Fri, May 15, 2020 at 23:09 Dallin Osmun 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 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 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 >> 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\nexpanding macro: >>> MyGoblet.query/2\nlib/testing.ex:8: Queries (module)
Re: [elixir-core:9490] Re: Proposal: IO.error/2
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 > > 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 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 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\nexpanding macro: >> MyGoblet.query/2\nlib/testing.ex:8: Queries (module)\n", >> position: nil, >> severity: :error >> } >> >> >> Even though the stack trace has a line number in it, that position is >> m