#Fixing command

91 messages Β· Page 1 of 1 (latest)

plush junco
#

Here's a fun error for y'all: https://paste.ecorous.org/dimozegebu

And here's the code that goes with it:

#[tauri::command]
async fn launch(name: &str) -> Result<(), String> {
    let config = config();
    let instance_a = Instance::from_path(config.get_instances_path().join(name));
    if instance_a.is_err() {
        return Err(instance_a.unwrap_err().to_string())
    }
    let instance = instance_a.unwrap();
    let components = merge_components(&config, &instance.config.components).await.unwrap();
    let prepared = prepare_launch(&config, &instance, &components, LaunchOptions::default()).await.unwrap();
    let launch = prepared.launch(true).await;
    if (launch.is_err()) {
        return Err(launch.unwrap_err().to_string());
    }
    Ok(())
}
#

The error is too large to post in discord

#

Please don't complain about my horrid error handling, I know it's bad :P

#

Please ping me when you reply, tysm

real compass
# plush junco Here's a fun error for y'all: https://paste.ecorous.org/dimozegebu And here's t...

Just as a note on your error handling, why not use ??

    let instance_a = Instance::from_path(config.get_instances_path().join(name))?;

Anyway, that's not why I'm here
Ther error to me seems to be that you're reading the Instance, whatever that is, from somewhere in the filesystem, which gives you a Reader, which indeed shouldn't be sent between threads, which is what happens when you run async functions, you should either pass the path forward and let other places read the file, or you should consume the reader and send the actual data to the async functions

plush junco
#

iirc because it wouldn't to_string the error

#

but maybe I'm wrong :P

plush junco
#

inc. the Instance type, from_path, the config type, the merge_components method, the prepare_launch method, and most of the types associated with them

real compass
plush junco
#

helixlauncher-core

#

I am part of that project, but I cannot change the library for this purpose

real compass
#

So many macro calls involved in the errors, hard to know which macros and where in them they're talking about... I'm sitting right now developing some macros and it's a b*tch and a half to debug because the error just points to where you're using the macro, not where in the macro it failed >.<

plush junco
#

tauri does seem to fuck with macros a lot

#

and macros aren't the easiest to work with

#

I can provide the proper error with better formatting if you want

#

It's massive though

real compass
#

It's ok I'm hot on the errors trail x)

plush junco
#

There it is if you want it

#

Much more useful imo

real compass
#

That function returns a reader instead of the full results

#

So we'll have to consume it

#

Before we can send it forward

#

Or hmm...

#

It should be returning Self

#

That's however the only place in the library that I can find that should be returning a reader, at least one related to your code

plush junco
#

Yeah this is very confusing

#

That's probably becuase it's 4am, but yk

#

the best code is written between 1am and 5am

real compass
#

I mean that error talks more about zipping, so the issue might not be in the code you've written. Hmm...

plush junco
#

yeah idfk

real compass
#

As a side note regarding the error handling, add the anyhow dependency and make all your String errors anyhow::Error, or the Result into anyhow::Result<Something>, it'll let you use the ? syntax instead

plush junco
#

I found the zips

#

I FOUND THE ZIPS

#

they're in the prepare_launch function

#

but what do I do about it

#

I very much need to extract the natives :P

real compass
#

Thinking... πŸ€” Hard to think without code to toss around while debugging

plush junco
#

I can always upload my current work to git

real compass
#

I mean you could, but I suspect there's too much code to go over for me to quickly verify nothing shady is on it, and I can't run unchecked code on the company computer, so I'd have to boot my personal computer and start a sandbox on it, which wouldn't have minecraft in it so the code probably wouldn't work because of that, it'd be a whole process and it's 5:28 here atm πŸ™ƒ

plush junco
#

It does download everything itself :P

#

but yeah

real compass
#

Based on digging through the library code, your errors and your command, my conclusion is that the compiler in my mind palace says it should be working >.< Like I can't find where it's getting that Read is being sent between threads, and if we assume the library work on its own without Tauri, then there's nothing Tauri specific I can think of that should be messing with the library. Everything seems to be implemented correctly, with proper returns and what not everywhere

plush junco
#

you're not doing much better on what time it is than me btw :P

#

The CLI works

real compass
#

Like sure some of the code in the library isn't the cleanest, for example functions should be like 10 lines long max before you split it up into new private functions, but I don't see anything wrong with it, and the code in your command looks good as well

Did you by any chance try copying the CLI code verbatim just to try it? Once ran inside an async command it should effectively be identical to running the code inside an async main with tokio

plush junco
#

I'm pretty sure it's 99% the same

#

Though I opted to remove some of the fancier options for an initial test

#
async fn launch_instance(
    config: &Config,
    name: String,
    world: Option<String>,
    dry_run: bool,
) -> Result<()> {
    let instance = Instance::from_path(config.get_instances_path().join(name))?;
    let components = merge_components(config, &instance.config.components).await?;

    let account_config =
        AccountConfig::new(config.get_base_path().as_path().join(DEFAULT_ACCOUNT_JSON))?;
    let prepared = prepare_launch(
        config,
        &instance,
        &components,
        LaunchOptions::default()
            .world(world)
            .account(account_config.selected()),
    )
    .await?;
    if !dry_run {
        prepared.launch(true).await?.wait().await?;
    } else {
        println!("{:?}", prepared);
    }
    Ok(())
}
#

that's the cli code

plush junco
real compass
plush junco
#

It's only the lack of an account config + no world or dry run option

#

The rest is pretty much verbatim

real compass
#

One difference is that the Config is owned by another parent context somewhere, so the configs lifetime will be different, which I mean could potentially be a thing in some cases but the compiler should've warned about that if that was the issue

plush junco
#

ah

#

in my code

#

I just have this in the same file

fn config() -> Config {
    return Config::new("dev.helixlauncher.HelixLauncher", "HelixLauncher").unwrap();
}
#

because it's used in multiple places

real compass
#

Should be fine, even if the config is created within the function its lifetime would still last throughout that function call which is where it gets consumed as well, so that lifetime shouldn't matter

plush junco
#

Oh shit

real compass
#

It's just the only difference I see that could be related to inter-thread stuff

plush junco
#

I've been working on this for 7hrs straight

#

Maybe I should take a break lmao

real compass
#

Could be an idea yes πŸ˜…

plush junco
#

I mean, the early AMs are the perfect time to work on code

#

imagine working on code during the day :P

real compass
#

Pff, yea right, I need 2 monster energy past midnight to really get into any kind of rhythm

plush junco
#

I don't run on monster

#

I run on hate for errors :P

#

So I just did a little bit of testing

#

The error disappears if I comment out the prepare launch line

#

(for testing purposes I stripped my method down to this)

#[tauri::command]
async fn launch(name: String) {
    let config = config();
    let instance = Instance::from_path(config.get_instances_path().join(name)).unwrap();
    let components = merge_components(&config, &instance.config.components).await.unwrap();
    let prepared = prepare_launch(&config, &instance, &components, LaunchOptions::default()).await.unwrap();
    let launch = prepared.launch(true).await.unwrap();
}
#

this is the main error

error[E0277]: `(dyn zip::aes_ctr::AesCipher + 'static)` cannot be sent between threads safely
   --> src/main.rs:78:1
    |
78  |   #[tauri::command]
    |   ^^^^^^^^^^^^^^^^^ `(dyn zip::aes_ctr::AesCipher + 'static)` cannot be sent between threads safely
...
89  |           .invoke_handler(tauri::generate_handler![
    |  _________________________-
90  | |             greet,
91  | |             get_instances,
92  | |             get_accounts,
93  | |             launch
94  | |         ])
    | |_________- in this macro invocation
    |
    = help: the trait `Send` is not implemented for `(dyn zip::aes_ctr::AesCipher + 'static)`
    = note: required for `Unique<(dyn zip::aes_ctr::AesCipher + 'static)>` to implement `Send`
#

(not the whole error)

real compass
#

I wanna say the issue is here https://github.com/HelixLauncher/HelixLauncher/blob/eb84f89743f9170c94079ce190bb956fd95e2089/helixlauncher-core/src/launch/prepared.rs#L262
But have nothing to back that up except it's where zip gets used
Which makes me think the instance.config.components.natives is improperly set up
Which makes me think the config is different between the CLI and the Tauri version
Other than that I'm really out of ideas because your Tauri command gets executed in a Tokio runtime, the same as the CLI function :/

plush junco
#

do note that instance.config is different to regular config

#

I'll ask the person who wrote that part of the code

#

looks like tauri uses its own async runtime which is apparently not compatible with that

#

maybe not its own async runtime but definitely stricter requirements

#

@real compass does tauri run tokio with some sort of stricter reqs?

#

That would definitely do it

real compass
#

Which is literally just a default Tokio runtime, nothing fancy

plush junco
#

// note to self; try moving zip handling code into a non-async function and calling that from async function

plush junco
#

@real compass I solved it in the end, it was a library issue

real compass