My first application - Some questions

Hey all!

This year is my second atempt to get into rust. Therefore I created a small "cross platform tray application" which gets a random wallpaper from "wallhaven.cc" and sets it as the current desktop background. Some parameters can be adjusted through a config file.

Now my question: I created a error.rs file which implements a custom error type "FreshwallError". This error implements every possible "from" trait for the different errors which could occur. I noticed that I somehow reimplemented the display of errors from different libraries which I use. This seems to be necessary, because my main function could return the "FreshwallError". Is it possible to return different error types without implementing all "from" traits for every possible error type? Or is this the common way to do this kind of thing?

I hope my question is clear enough :slight_smile:
You can find the code here: http://github.com/geaz/freshwall

Thank you and best regards!

P.S.: If you see something which also could be done better, please tell me!

Right now your error is kinda stringly-typed and is more or less emulating the functionality that you'd get by using an Error trait object, so maybe it would make more sense to simply do that instead.

If you wanted to go that route then you'd change your main function and other functions to return Result<(), Box<dyn std::error::Error> instead of the custom error type.

1 Like

Perfect, that was what I was searching for! Thank you very much!

Hello, you can try to use https://github.com/rust-lang-nursery/failure

In my code I've used Result<(), Box<std::error::Error> (without the dyn).

Is the dyn implied in my case? Does Rust still perform dynamic dispatch in my example?

I've only just started learning about dynamic dispatch in Rust in the last couple days.

dyn is the new, recommended way for how to write out that you're using a trait object. So Box<dyn Trait> and Box<Trait> are the same thing and are both performing dynamic dispatch. The reason the dyn keyword was added is to make it more clear when this dynamic dispatch is happening.

1 Like

I read a bit about static dispatch and dynamic dispatch. Is it correct, that it is better for performance to use an "own" error object? Because the compiler would then be able to do static dispatching?

One more question: I saw, that one of the error objects in a library I use doesn't implement the Error trait. Therefore the compiler not able to dispatch it to this trait. What would be the best way to overcome this problem? A own error object? Or is there a better way?

Static dispatch isn't necessarily better 100% of the time. Unboxed error types occupy space on the stack like any other struct or enum, and it can happen that repeatedly copying larger error types around becomes more expensive than going through dynamic dispatch. This isn't really something you can eyeball though. If the performance difference is something that matters enough then you would need to profile your application and find hard numbers to decide which method works best.

As for the error type that doesn't impl Error, you probably could convert it into your own error type if you like. For example, you could make your own enum that wraps around all of the other enums that you receive. Or you could still convert the errors to some other internal representation, but you'd want it to be a bit more robust than one String to rule them all.

Alternatively you could make a PR to the other library so that their error impls the Error trait so that you can keep doing dynamic dispatch.

1 Like