Perhaps you addressed this, but how would IO.error behave when not 
compiling things? How would it behave if you remote console into a running 
system and call IO.error?

On Monday, May 11, 2020 at 11:33:40 PM UTC-4, Dallin Osmun wrote:
>
> I understand at first glance this proposal might not seem necessary. I 
> wanted to give some insight into how I got here. I'd like to outline a 
> couple of the alternatives I tried and some of the issues I ran into while 
> doing so.
>
> As a reminder: the goal is to emit multiple error diagnostics during the 
> compilation step and fail the compilation.
>
> *Let's stick with `raise/1`*
> Everyone is already using raise to emit errors from macros. The compiler 
> diagnostic that is emitted from raise is missing a position but it does 
> have a stacktrace. While the original frame in that trace does point to 
> your macro, it probably still isn't the correct line. Take the following 
> pseudocode. raise will cause a stacktrace that points to `query` on line 1 
> when your actual error is on line 3. Currently, raise does not and cannot 
> know exactly where your error is.
>
> ```
> 1. query Thing do
> 2.   id
> 3.   error_here
> 4. end
> ```
>
> *So add `raise/2`*
> Maybe we enhance raise so it takes an optional stacktrace as a second 
> argument like IO.warn does. While I think this is a great idea, it doesn't 
> meet one of the two criteria above (emit multiple errors). For the record 
> though, I do think there are cases out there where rather than let your 
> macro get into an inconsistent state you would want to raise an error and 
> stop compilation. If we allowed a custom stacktrace to be passed in to 
> raise then the error diagnostic it emitted would be more useful.
>
> *Why not use IO.warn/2 with the `warnings_as_errors` flag?*
> This solution does indeed solve both my criteria: multiple errors are 
> emitted and the build fails. But the developer experience is not ideal:
> - I am forcing my users to add a compiler flag to their project. It's one 
> more thing to remember when using my library.
> - As a macro author I would like to emit both warnings and errors. If I 
> can only emit warnings (which are treated as errors) then I am unable to 
> distinguish between the two.
> - This forces ALL warnings in your project to be treated as errors which 
> may not be desirable in some cases.
>
> *How about IO.warn/2 and return a raise if you hit any warnings?*
> So let's imagine then that I use IO.warn to report all of my errors. If I 
> had to report any errors then I'll make my macro output an AST for `raise 
> "broken macro: check the logs"`. I don't have to force the 
> `warnings_as_errors` flag on my users this way and I am able to emit 
> multiple errors. But now the compilation is successful. I have to rely on 
> my users actually exercising their code or having a good test suite to find 
> out that the output of the macro isn't actually going to work.
>
>
> On Monday, May 4, 2020 at 5:37:14 PM UTC-6, Dallin Osmun wrote:
>>
>> I propose that we add `IO.error/2` which matches the signature of 
>> `IO.warn/2`. It emits error diagnostics/messages instead of warnings and it 
>> causes the compile step to finish with :error.
>>
>>
>> *Reasoning*
>>
>> Often when building a macro you'll do some validation and `raise` an 
>> error if something isn't right. This creates a poor experience for the 
>> person using the macro for two reasons:
>> 1. You can only raise one error at a time
>> 2. You don't get a good picture of where the error is because your whole 
>> editor turns red
>>
>> You can solve both of those problems by using `IO.warn/2`. You can emit 
>> multiple warnings in a single compile step and you can pass in a stacktrace 
>> which gets turned into a Compiler Diagnostic that in turn, creates good 
>> editor hints. But now the compilation succeeds and you're left in a bad 
>> state.
>>
>> I think it is useful to see multiple errors at a time because it shortens 
>> the feedback loop. It also gives more context and can help you realize 
>> where the root cause of your issue lies.
>>
>> I think it would be useful to have a function that shared the properties 
>> of `IO.warn/2` and `raise/1`:
>> - I can emit multiple messages during a single compilation run
>> - These messages are output as Compiler Diagnostic errors
>> - Invoking this function will ultimately cause the compilation step to 
>> result in an :error
>>
>>
>> *Examples*
>>
>> Today in Ecto Query, this snippet will cause the entire file to turn red 
>> because we mistakenly used sort_by instead of order_by.
>> query p in Product, sort_by: p.price
>>
>> Lets assume we forgot to load the :user type in this Absinthe Schema. We 
>> have two errors but only one gets displayed. Once again, the entire editor 
>> turns red. If instead we saw each line that referenced :user turn red it 
>> might remind us more quickly that we forgot to call `import_types 
>> MyApp.UserTypes`.
>> query name: "Query" do
>>   field :user, :user, resolve: &MyApp.Users.get_user/3
>>   ...
>>   field :users, list_of(:user), resolve: &MyApp.Users.list_user/3
>>   ...
>> end
>>
>> I'm currently working on a library to create GraphQL queries. I can 
>> detect three errors in the following snippet. Today I can only report one 
>> at a time and am greeted with the wall of red. If I switch to `IO.warn/2` I 
>> can report them all and see nice editor hints but my user is left with 
>> broken code after compile.
>> query do
>>   user(id: "should_be_a_number") do # wrong type for id
>>     firstNam # misspelled, should be firstName
>>     lastName do # lastName should not have a do...end block
>>       name
>>     end
>>   end
>> end
>>
>>
>> *Code*
>>
>> Here is a patch that adds `IO.error/2`:
>> https://github.com/elixir-lang/elixir/compare/master...numso:io-error
>>
>>

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/b35883ee-f773-4b9b-95e0-3f7d141d75e5%40googlegroups.com.

Reply via email to