anyhow: Return nested/wrapped errors - rust

use anyhow::Context;
fancy_module::run()
.await
.with_context(|| {
format!("An error has been found")
})?;
From what I understand, when run returns an error, we return "An error has been found". But this message is not really meaningful. I would like to also return the error that run returns. Something like format!("An error has been found {}", e). How do I get e returned by run?
I could do that in multiple lines of code. By fetching the result of run and then having a match statement. Is there a nicer way of doing that?

From what I understand, when run returns an error, we return "An error has been found".
Not correct! context and with_context create a wrapper around the underlying error value to introduce additional context, but the original error is kept within!
Once you try displaying the error, you will see something of this sort:
Error: An error has been found
Caused by:
No such file or directory (os error 2)
(This also shows that "An error has been found" is a poor choice of words for creating additional context.)
I would like to also return the error that run returns. Something like format!("An error has been found {}", e).
That used to be a reasonable design decision in the past, but the current guidelines for error type design are against including the source error in the display message, unless that source error is also not reachable in the source error chain. The context methods will put the error in the source chain, so including that error's message into the top level error's message is ill advised.
How do I get e returned by run?
See the chain method in order to traverse the chain of source errors and so enable you to peek into underlying causes. Still, anyhow's error type was mostly designed to be opaque. If you need better introspection into what the error entails or easier pattern matching on errors, consider using a structural error type instead of anyhow::Error (snafu or thiserror can help you build them).
See also:
Should an Error with a source include that source in the Display output?
What is the difference between "context" and "with_context" in anyhow?
Simplier way to return custom error type with anyhow::Error?

Related

Nice Error Messages for "no viable alternative at input '<EOF>'" in ANTLR4

I want to show more beautiful error message to my users.
For example if someone types integer i= the error message no viable alternative at input '<EOF>' appears. That's totally fine and predictable due to my grammar rules but I'm figuring out ways to improve those messages. If the = is missing in the example above the message changes to mismatched input '<EOF>' expecting '='. Again predictable but I can do more stuff on things like this in my code than on a general input error.
Should I catch them in the code and try to evaluate which cases is meant? Or is there a better way to handle this?
Typically you'd create your own error listener and add it to the parser where you can deal with the error yourself. For that remove any existing error listeners (one for the console is automatically registered by default), by calling parser.removeErrorListeners();. Define an own error listener class derived from BaseErrorListener and add an instance of that to your parser via parser.addErrorListener(yourListener);. You can see an example of such a custom error listener in the ANTLR runtime (search for XPathLexerErrorListener). Override the syntaxError method and use the provided info to generate your own error message. There is already a message passed in to this method (in addition to other stuff like line + char position, exception etc.), which you cannot customize as it comes directly from generated code. So best is probably to leave that alone and start from scratch (the passed in exception is your best option you have).

Python 3: Shared packages: Returning results and errors from imported functions

I am creating a Python 3.4 module (possibly sharing upon PyPi) and I want to clarify what is the proper and expected way of handling results and errors returned from an imported function from my package.
I am reading Effective Python, but I am still confused.
There are so many possibilities, I just want to handle Python 3 results from an imported function properly.
Should the result and error handling of an imported function:
Return result but then throw exception upon error?
Return a tuple of result, error?
And if the preferred choice is tuple, then should:
Upon success, result can be anything (is this correct?), but then should error be None or should it be False?
Upon failure, then should result be None or should it be False, and error should then return internally caught Exception or what?
Thank you for your feedback
You should throw an exception upon error. This enable lot of advance construction like proper object destruction like with the with keyword for instance.
If you raise an exception you don't care about result as your function will not return "in a normal way". So the instruction on the left on your function call will not be executed as well the rest of the try block.

VS2012 error every time I start. Message is not helpful - any suggestions?

WHen I start VS2012 I always get an exception tellng me to look at ActivityLog.xml. Here is what I see- useless to me. Hoping someone else has seen this before.
Also - VS2012 eats 100% of the CPU on the machine at time. Hoping the two are related and fixable.
System.ComponentModel.Composition.CompositionException: The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.
1) The current type, SquaredInfinity.Foundation.Configuration.Services.IConfigurationService, is an interface and cannot be constructed. Are you missing a type mapping?
Resulting in: Resolution of the dependency failed, type = "SquaredInfinity.Foundation.Configuration.Services.IConfigurationService", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, SquaredInfinity.Foundation.Configuration.Services.IConfigurationService, is an interface and cannot be constructed. Are you missing a type mapping?
-----------------------------------------------
At the time of the exception, the container was:
Resolving SquaredInfinity.Foundation.Configuration.Services.IConfigurationService,(none)
Resulting in: An exception occurred while trying to create an instance of type &apos;#Btb.#Rtb&apos;.
Resulting in: Cannot activate part &apos;#Btb.#Rtb&apos;.
Element: #Btb.#Rtb --> #Btb.#Rtb
Resulting in: Cannot get export &apos;#Btb.#Rtb (ContractName="Microsoft.VisualStudio.Text.Classification.IClassifierProvider")&apos; from part &apos;#Btb.#Rtb&apos;.
Element: #Btb.#Rtb (ContractName="Microsoft.VisualStudio.Text.Classification.IClassifierProvider") --> #Btb.#Rtb
at System.ComponentModel.Composition.Hosting.CompositionServices.GetExportedValueFromComposedPart(ImportEngine engine, ComposablePart part, ExportDefinition definition)
at System.ComponentModel.Composition.Hosting.CatalogExportProvider.GetExportedValue(CatalogPart part, ExportDefinition export, Boolean isSharedPart)
at System.ComponentModel.Composition.Hosting.CatalogExportProvider.CatalogExport.GetExportedValueCore()
at System.ComponentModel.Composition.Primitives.Export.get_Value()
at System.ComponentModel.Composition.ExportServices.GetCastedExportedValue[T](Export export)
at System.ComponentModel.Composition.ExportServices.<>c__DisplayClass42.<CreateStronglyTypedLazyOfTM>b__1()
at System.Lazy1.CreateValue()
at System.Lazy1.LazyInitValue()
at System.Lazy1.get_Value()
at Microsoft.VisualStudio.Text.Utilities.GuardedOperations.InvokeMatchingFactories[TExtensionInstance,TExtensionFactory,TMetadataView](IEnumerable1 lazyFactories, Func2 getter, IContentType dataContentType, Object errorSource)
Is your VSCommands extension up to date?
There was a compatibility issue which could produce similar stack trace, and it was fixed in latest release.

How does Langage.Haskell.TH.report work?

Unfortunately, many Template Haskell functions have absolutely no documentation at all. One such function is report. It takes a Bool and a String, and produces a compilation error with the specified string as the error message. Does anybody have any clue what the hell the Bool is for? As best as I can tell, either value does exactly the same thing...
If the Bool is True, an error is reported; if it is False, a "warning" is reported, meaning that the template code will continue to run to collect more "warnings."
Looking at the source code, report calls qReport, which is a method of some class called Quasi. This method actually has some damned documentation - though only a tiny snippet. I quote:
Report an error (True) or warning (False) ...but carry on; use fail to stop
So it seems to make my TH splice crash with an appropriate error message, I just need to call fail instead. Hopefully this information will be useful to anyone else trying to figure that out...

compiler warning on (ambiguous) method resolution with named parameters

One question regarding whether the following code should yield a compiler warning or not (it doesn't). It declares two methods of the same name/return type, one has an additional named/optional parameter with default value.
NOTE: technically the resolution isn't ambiguous, because the rules clearly state that the first method will get called. See here, Overload resolution, third bullet point. This behavior is also intuitive to me, no question.
public void Foo(int arg) { ... }
public void Foo(int arg, bool bar = true) { ...}
Foo(42); // shouldn't this give a compiler warning?
I think a compiler warning would be kind of intuitive here. Though the code technically is clean (whether it is a sound design is a different question:)).
I disagree that it needs a warning, actually. The main issue is, that code is potentially legitimate, and if that's the case you would have to explicitly disable the warning.
What I mean is, in general when you get a warning, you will be able to change your code to get rid of the warning (and presumably make the code better at the same time). But in this case, it may be that you did it like that intentionally and would not be able to change your code to get rid of the warning.
For example, the "unreachable code" warning is something you can just delete the unreachable code to get rid of the warning. Or the "could not find reference" warning - this is usually a signal that you're going to get "undefined type" errors, but if not then you can simply delete the reference. Or maybe "A previous catch clause already catches all exceptions" warning: in this case, you need to change your code so that either the new clause comes before the catch-all, or remove the catch altogether.
But the point is that in every case when you get a warning, you should change your code, and making the change will always result in "better" code. However, in the case of this question, the call is not ambiguous (as far as the compiler is concerned) and I don't think you can argue that it's always a mistake to write code like that, so therefore there shouldn't be a warning.
If the compiler issued a warning about every case where you do something that's probably not the best idea, then we'd be inundated with warnings!
Warnings are to notify programmers of potentially dumb mistakes. This is an area that could generate a dumb mistake, so yes, it should generate a warning. Are you trying to form a petition?

Resources