Hacker Newsnew | past | comments | ask | show | jobs | submit | more seivan's commentslogin

You forgot how beholden the visa holder is, which aside to cost is the other benefit.


Static typing is a must unless the compromise is worth it. For instance even without static typing Elixir is worth it for OTP and the preemptive scheduler (VM) is just a bonus.

But then you also have to include what type of application it is. Real time or soft real time, etc.


How did AWS mess up errors?


Maybe I am holding it wrong.

Here is one piece of the problem:

  while let Some(page) = object_stream.next().await {
        match page {
            // ListObjectsV2Output
            Ok(p) => {
                if let Some(contents) = p.contents {
                    all_objects.extend(contents);
                }
            }
            // SdkError<ListObjectsV2Error, Response>
            Err(err) => {
                let raw_response = &err.raw_response();
                let service_error = &err.as_service_error();
                error!("ListObjectsV2Error: {:?} {:?}", &service_error, &raw_response);
                return Err(S3Error::Error(format!("ListObjectsV2Error: {:?}", err)));
            }
        }
    }


Out of curiosity, why are you borrowing that many times? The following should work:

    while let Some(page) = object_stream.next().await {
        match page {
            // ListObjectsV2Output
            Ok(p) => {
                if let Some(contents) = p.contents {
                    all_objects.extend(contents);
                }
            }
            // SdkError<ListObjectsV2Error, Response>
            Err(err) => {
                let raw_response = err.raw_response();
                let service_error = err.as_service_error();
                error!("ListObjectsV2Error: {:?} {:?}", service_error, raw_response);
                return Err(S3Error::Error(format!("ListObjectsV2Error: {:?}", err)));
            }
        }
    }
I would have written it this way

    while let Some(page) = object_stream.next().await {
        let p: ListObjectsV2Output = page.map_err(|err| {
            // SdkError<ListObjectsV2Error, Response>
            let raw_response = err.raw_response();
            let service_error = err.as_service_error();
            error!("ListObjectsV2Error: {service_error:?} {raw_response:?}");
            S3Error::Error(format!("ListObjectsV2Error: {err:?}"))
        })?;
        if let Some(contents) = p.contents {
            all_objects.extend(contents);
        }
    }
although if your crate defines `S3Error`, then I would prefer to write

    while let Some(page) = object_stream.next().await {
        if let Some(contents) = page?.contents {
            all_objects.extend(contents);
        }
    }
by implementing `From`:

    impl From<SdkError<ListObjectsV2Error, Response>> for S3Error {
        fn from(err: SdkError<ListObjectsV2Error, Response>) -> S3Error {
            let raw_response = err.raw_response();
            let service_error = err.as_service_error();
            error!("ListObjectsV2Error: {service_error:?} {raw_response:?}");
            S3Error::Error(format!("ListObjectsV2Error: {err:?}"))
        }
    }


Excellent! Thank you!

My problem is that I should have something like

(http_status, reason) where http_status is a String or u16, reason is a enum with SomeError(String) structure. So essentially having a flat meaningful structure instead of this what we currently have. I do not have any mental model about the error structure of the AWS libs or don't even know where to start to create that mental model. As a result I just try to turn everything to a string and return it altogether hoping that the real issue is there somwhere in that structure.

I think the AWS library error handling is way to complex for what it does and one way we could improve that if Rust had a great example of a binary (bin) project that has lets say 2 layers of functions and showing how to organize your error effectively.

Now do this for a lib project. Without this you end up with this hot mess. At least this is how I see it. If you have a suggestion how should I return errors from a util.rs that has s3_list_objects() to my http handler than I would love to hear what you have to say.

Thanks for your suggestions anyway! I am going to re-implement my error handling and see if it gives us more clarity with impl.


You might want to look at anyhow and thiserror, the former for applications and for libraries the latter. thiserror "just" makes it easier to do what I suggested of writing a manual `impl From` so that `?` can transform from the error you're getting to the error you want. When the API you consume is very granular, that's actually great because it means that you have a lot of control over the transformation (it's hard to add detail that isn't already there), but it can be annoying when you don't care about that granularity (like when you just want to emit an error during shutdown or log during recovery).

https://momori.dev/posts/rust-error-handling-thiserror-anyho...

burntsushi has a good writeup about their difference in usecase here:

https://www.reddit.com/r/rust/comments/1cnhy7d/whats_the_wis...


You don’t need that application that sounds like a narcotic.

That’s built in, “man caffeinate”.


The way I understand it, its for those who can't help but to fix B while working on A and want to make sure that they are two different PRs? The way I do it is after B is done, I just create a new branch and point B to A in the PR. A is pointing to dev/master/upstream. Does JJ make this workflow more convenient?


Yep! And it makes it convenient even when you need to make changes or add new commits onto A. B is constantly stitched up to remain a child of A and incorporate its fixes.

It also makes it simple and easy to split B and A apart such that both their parents are `main` if they’re unrelated.

You can also go hog-wild. I was working on a big refactor recently. I made independent changes A, B, C, and D (each one to three commits). I then wanted to work on code that assumed all of these commits were available, so I made a merge commit E that combined them. I then made changes F that depended on that refactor, so was a child of E.

Managing this was simple. If I needed to make updates or tweaks to A-D, E and F were updated to incorporate them automatically. `jj absorb` even meant that doing these types of changes was almost zero work: I could make a bunch of changes and the tool would know in which parent commit they belonged.

None of this was merged in yet. When I was ready, PRs went out for A-D. When they each merged into `main`, E became a no-op and was discarded. F became its own PR. This is something I never would have done in git because having multiple threads of unmerged code is a colossal hassle.


You'd probably like reading about the megamerge workflow. I and others have linked some articles in a few comments here already.


The training course to sneak past behind enemy lines for the SF role was the hardest, lol.


I loved how slow that game was, my favourite map was the bridge one, before they added the ridge so you could circumvent the bridge as a chokepoint.


What’s the monetisation strategy here? Raising 5M for what exactly?


If you want cohesion between entities pathfinding, adjust the cost when you do the pathfinding for tiles that has friendlies on them to be lower than their base cost.

The way to think about water crossing with naval transports, is to consider those things to be conditions. You already have a set of condition when pathfinding. Just add another case for water. Make it so the requirement is that you’re either on a ship or there is a ship on the adjacent tile you checked previously, e.g N-1. If valid, set a flag and now every tile check that is water should be appropriate.


This is the address they gave to the driver,full stop. After the job’s done, you can’t just tack on extra requests like it’s a buffet. He delivered exactly what you asked, not a mind reading bonus round. It’s not his fault you gave the wrong address, he’s not clairvoyant.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: