feel like i must be doing something
feel like i must be doing something stupid but trying to run the workflows-starter and getting a 500 when trying to create a workflow:
will thread the rest of my src code. is there a specific url you're supposed to hit or something?
[wrangler:inf] GET / 500 Internal Server Error (48ms)
[wrangler:inf] GET /favicon.ico 404 Not Found (2ms)
id null
creating new instance RpcStub {}
[wrangler:err] TypeError: Cannot destructure property 'id' of 'undefined' as it is undefined.
at async Object.fetch (file:///Users/srb/projects/elater-cf-workflow/workflows-starter/src/index.ts:84:18)
at async jsonError (file:///Users/srb/projects/elater-cf-workflow/workflows-starter/node_modules/wrangler/templates/middleware/middleware-miniflare3-json-error.ts:22:10)
at async drainBody (file:///Users/srb/projects/elater-cf-workflow/workflows-starter/node_modules/wrangler/templates/middleware/middleware-ensure-req-body-drained.ts:5:10)
[wrangler:inf] GET / 500 Internal Server Error (48ms)
[wrangler:inf] GET /favicon.ico 404 Not Found (2ms)
id null
creating new instance RpcStub {}
[wrangler:err] TypeError: Cannot destructure property 'id' of 'undefined' as it is undefined.
at async Object.fetch (file:///Users/srb/projects/elater-cf-workflow/workflows-starter/src/index.ts:84:18)
at async jsonError (file:///Users/srb/projects/elater-cf-workflow/workflows-starter/node_modules/wrangler/templates/middleware/middleware-miniflare3-json-error.ts:22:10)
at async drainBody (file:///Users/srb/projects/elater-cf-workflow/workflows-starter/node_modules/wrangler/templates/middleware/middleware-ensure-req-body-drained.ts:5:10)
3 Replies
this is again just from creating the workflows-starter, my
plus this workflow class:
wrangler.toml is
ohh thank you that worked
src/index.ts
is this default function:
export default {
async fetch(req: Request, env: Env): Promise<Response> {
let url = new URL(req.url);
if (url.pathname.startsWith('/favicon')) {
return Response.json({}, { status: 404 });
}
let id = url.searchParams.get('instanceId');
console.log('id', id);
if (id) {
let instance = await env.MY_WORKFLOW.get(id);
return Response.json({
status: await instance.status(),
});
}
console.log('creating new instance', await env.MY_WORKFLOW.create);
let instance = await env.MY_WORKFLOW.create();
console.log('instance', instance);
return Response.json({
id: instance.id,
details: await instance.status(),
});
},
};
export default {
async fetch(req: Request, env: Env): Promise<Response> {
let url = new URL(req.url);
if (url.pathname.startsWith('/favicon')) {
return Response.json({}, { status: 404 });
}
let id = url.searchParams.get('instanceId');
console.log('id', id);
if (id) {
let instance = await env.MY_WORKFLOW.get(id);
return Response.json({
status: await instance.status(),
});
}
console.log('creating new instance', await env.MY_WORKFLOW.create);
let instance = await env.MY_WORKFLOW.create();
console.log('instance', instance);
return Response.json({
id: instance.id,
details: await instance.status(),
});
},
};
export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
// Can access bindings on `this.env`
// Can access params on `event.payload`
const files = await step.do('my first step', async () => {
// Fetch a list of files from $SOME_SERVICE
return {
inputParams: event,
files: [
'doc_7392_rev3.pdf',
'report_x29_final.pdf',
'memo_2024_05_12.pdf',
'file_089_update.pdf',
'proj_alpha_v2.pdf',
'data_analysis_q2.pdf',
'notes_meeting_52.pdf',
'summary_fy24_draft.pdf',
],
};
});
const apiResponse = await step.do('some other step', async () => {
let resp = await fetch('https://api.cloudflare.com/client/v4/ips');
return await resp.json<any>();
});
await step.sleep('wait on something', '1 minute');
await step.do(
'make a call to write that could maybe, just might, fail',
// Define a retry strategy
{
retries: {
limit: 5,
delay: '5 second',
backoff: 'exponential',
},
timeout: '15 minutes',
},
async () => {
// Do stuff here, with access to the state from our previous steps
if (Math.random() > 0.5) {
throw new Error('API call to $STORAGE_SYSTEM failed');
}
}
);
}
}
export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
// Can access bindings on `this.env`
// Can access params on `event.payload`
const files = await step.do('my first step', async () => {
// Fetch a list of files from $SOME_SERVICE
return {
inputParams: event,
files: [
'doc_7392_rev3.pdf',
'report_x29_final.pdf',
'memo_2024_05_12.pdf',
'file_089_update.pdf',
'proj_alpha_v2.pdf',
'data_analysis_q2.pdf',
'notes_meeting_52.pdf',
'summary_fy24_draft.pdf',
],
};
});
const apiResponse = await step.do('some other step', async () => {
let resp = await fetch('https://api.cloudflare.com/client/v4/ips');
return await resp.json<any>();
});
await step.sleep('wait on something', '1 minute');
await step.do(
'make a call to write that could maybe, just might, fail',
// Define a retry strategy
{
retries: {
limit: 5,
delay: '5 second',
backoff: 'exponential',
},
timeout: '15 minutes',
},
async () => {
// Do stuff here, with access to the state from our previous steps
if (Math.random() > 0.5) {
throw new Error('API call to $STORAGE_SYSTEM failed');
}
}
);
}
}
#:schema node_modules/wrangler/config-schema.json
name = "workflows-starter"
main = "src/index.ts"
compatibility_date = "2024-10-22"
[observability]
enabled = true
head_sampling_rate = 1 # optional. default = 1.
[[workflows]]
# name of your workflow
name = "workflows-starter"
# binding name env.MYWORKFLOW
binding = "MY_WORKFLOW"
# this is class that extends the Workflow class in src/index.ts
class_name = "MyWorkflow"
#:schema node_modules/wrangler/config-schema.json
name = "workflows-starter"
main = "src/index.ts"
compatibility_date = "2024-10-22"
[observability]
enabled = true
head_sampling_rate = 1 # optional. default = 1.
[[workflows]]
# name of your workflow
name = "workflows-starter"
# binding name env.MYWORKFLOW
binding = "MY_WORKFLOW"
# this is class that extends the Workflow class in src/index.ts
class_name = "MyWorkflow"
I'm surprised this bug still exists after a week? Hope it's not stopping people trying out workflows
Just ran into this as well and wanted to let others know to pass an empty object.