You're right that components should intuitively pend forever. But with Async UI, the line between a component and a normal async function is blurry; our login_form eventually returns, so it is a normal async function, but it also renders something, so it is kind of a component...
Concretely the login_form function works by racing a render (a true, never-completing component) with a "listener" future that completes when the user submits their login. Once the listener completes, the race is over and the render future gets dropped. We can then return from login_form.
The async control flow is not directly inspired by anything. It is a cool side effect of using async for everything that I myself only discovered once I started writing examples.
Async UI as a whole is inspired by the simple fact that UI is an effect system[1], and async is also an effect system.
Re error handling:
There's no real support yet. For now when I hit an error I just render nothing. I might add support for components returning Result<_, _> in the future.