workers-rs icon indicating copy to clipboard operation
workers-rs copied to clipboard

[ISSUE] Durable Object Endpoints not accessible. Error: Failed to load endpoint

Open WillDera opened this issue 1 year ago • 1 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

What version of workers-rs are you using?

0.3.1

What version of wrangler are you using?

3.68.0

Describe the bug

Following the instructions here I was able to create a durable object, and this is reflected on my cloudflare dashboard but I cant seem to figure out how to access it.

This is my code:

use gloo_utils::format::JsValueSerdeExt;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use wasm_bindgen::JsValue;
use worker::{durable_object, *};

#[durable_object]
pub struct StoreDurableObject {
    state: State,
    amount: i64,
    env: Env,
}

#[event(fetch)]
async fn main(req: Request, env: Env, _ctx: Context) -> Result<Response> {
    let router = Router::new();

    router
        .on_async("/durable", |req, ctx| async move {
            durable_object_handler(req, ctx).await
        })
        .run(req, env)
        .await
}

async fn durable_object_handler(mut req: Request, ctx: RouteContext<()>) -> Result<Response> {
    let body = match req.clone().unwrap().json::<StoreObject>().await {
        Ok(res) => res,
        Err(e) => return Response::error(format!("Failed to parse JSON: {}", e), 400),
    };

    let store_object = match ctx.durable_object("STORE") {
        Ok(res) => res,
        Err(e) => {
            return Response::error(
                format!("Failed to get Durable Object Namespace: {}", e),
                400,
            )
        }
    };

    console_log!("Store Object: {:?}", store_object.as_ref());
    let id = store_object.id_from_name(&body.store_id).unwrap();
    console_log!("id: {:?}", id.to_string());
    let stub = id.get_stub();

    // Get the request body as a String
    let body = match req.json::<Value>().await {
        Ok(json) => JsValue::from_serde(&json)?,
        Err(err) => return Response::error(format!("Something went wrong: {err:?}"), 500),
    };

    console_log!("DATA: {:#?}", body);

    // Create a new request
    let new_req = Request::new_with_init(
        "/dobj",
        RequestInit::new()
            .with_method(req.method())
            .with_body(Some(body))
            .with_headers(req.headers().to_owned()),
    )?;

    console_log!("REQUEST: {:?}", new_req);

    match stub.unwrap().fetch_with_request(new_req).await {
        Ok(res) => Response::ok(format!("Response: {:?}", res)),
        Err(err) => Response::error(format!("Err: {err:?}"), 500),
    }
}

#[durable_object]
impl DurableObject for StoreDurableObject {
    fn new(state: State, env: Env) -> Self {
        Self {
            state,
            amount: 0,
            env,
        }
    }

    async fn fetch(&mut self, req: Request) -> Result<Response> {
         let env = self.env.clone().into();

         let router = Router::with_data(self);

         router
             .post_async("/dobj", |mut req, ctx| async move {
                 let mut _self = ctx.data.borrow_mut();

                 let mut storage = _self.state.storage();

                 if let Ok(body) = req.json::<StoreObject>().await {
                     _self.amount = body.amount;
                     storage.put("amount", _self.amount).await?;
                     Response::ok("Amount Inserted Into Durable Object")
                 } else {
                     Response::error("Bad Request", 400)
                 }
             })
             .run(req, env)
         .await
    }
}

And this is my curl request (from postman):

curl --location 'https://dev1.xxxxx.com/durable' \
--header 'Content-Type: application/json' \
--data '{
    "store_id": "Store1",
    "amount": 25
}'

And this is the response (as text) I get back

Err: JsError("Error: TypeError: Fetch API cannot load: /dobj - Cause: TypeError: Fetch API cannot load: /dobj")

I'm not sure what I am doing wrong. Any help would be appreciated.

Steps To Reproduce

No response

WillDera avatar Aug 05 '24 13:08 WillDera

Could this be due to using GET method, when DO's router only implements POST? Can you share your wrangler.toml as well?

kflansburg avatar Aug 27 '24 12:08 kflansburg