Skip to content

Commit

Permalink
Merge pull request #154 from upstash/DX-999-feedback-2
Browse files Browse the repository at this point in the history
Workflow: Context in Failure Function
  • Loading branch information
ogzhanolguncu authored Aug 20, 2024
2 parents e12cbff + 1bd7906 commit 7ac5f5d
Show file tree
Hide file tree
Showing 21 changed files with 499 additions and 241 deletions.
4 changes: 2 additions & 2 deletions examples/workflow/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ First, set the environment variables `QSTASH_TOKEN`, `QSTASH_URL`, `QSTASH_CURRE
The `bootstrap.sh` script makes it possible to start an examplew workflow project and create a Ngrok tunnel in one script. To run it, simply choose the framework and the endpoint you would like to choose as default:

```
bash bootstrap.sh <example-framework> <workflow-endpoint>
bash bootstrap.sh <example-framework>
```

Here is an example call:
Expand All @@ -30,7 +30,7 @@ bash bootstrap.sh nextjs path
You will still be able to use endpoints other than `path`. `path` will simply be what the home page will have as default endpoint.

Here is what the script does in a nutshell:
- create a Ngrok tunnel from `localhost:3000`
- create a Ngrok tunnel from `localhost:3001`
- Public URL of the tunnel is inferred from Ngrok logs.
- `context.ts` file in `@upstash/qstash` is updated with the URL from Ngrok.
- `@upstash/qstash` is built and installed in the picked framework example
Expand Down
39 changes: 5 additions & 34 deletions examples/workflow/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,16 @@ fi
# store project argument
project_arg="$1"

# Store the path argument
path_arg="$2"

# Start ngrok and capture the public URL
ngrok http localhost:3001 --log=stdout > ngrok.log &
NGROK_PID=$!
sleep 5 # Allow some time for ngrok to start

# Extract the ngrok URL from the logs
ngrok_url=$(grep -o 'url=https://[a-zA-Z0-9.-]*\.ngrok-free\.app' ngrok.log | cut -d '=' -f 2 | head -n1)
export UPSTASH_WORKFLOW_URL=$ngrok_url

# Append the path argument to the ngrok URL
if [ "$project_arg" == "nuxt" ]; then
full_url="${ngrok_url}/api/${path_arg}"
else
full_url="${ngrok_url}/${path_arg}"
fi

# Navigate to the parent directory
cd ../..


# Update the URL in the context.ts file
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' "s|this\.url = .*|this.url = '$full_url';|" src/client/workflow/context.ts
else
sed -i "s|this\.url = .*|this.url = '$full_url';|" src/client/workflow/context.ts
fi

# Install dependencies
bun install

# Build the project
bun run build

# Navigate to the examples/workflow directory
cd examples/workflow/${project_arg}

# Install the local package
npm install @upstash/qstash@file:../../../dist

final_path=$ngrok_url?function=$path_arg
final_path=$ngrok_url
echo "Setup complete. Full URL: $final_path"
echo "ngrok is running. Press Ctrl+C to stop it."

Expand All @@ -71,6 +39,9 @@ else
echo "Unsupported OS type: $OSTYPE"
fi

# go to project directory
cd $project_arg

# Start next.js server
npm run dev
# Wait for ngrok to be manually stopped
Expand Down
4 changes: 2 additions & 2 deletions examples/workflow/nextjs/app/-call-qstash/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { NextRequest } from 'next/server';
const client = new Client({ baseUrl: process.env.QSTASH_URL!, token: process.env.QSTASH_TOKEN! });

export const POST = async (request: NextRequest) => {
const { baseUrl, route, payload } = await request.json() as {baseUrl: string, route: string, payload: unknown};
const { route, payload } = await request.json() as {route: string, payload: unknown};

try {
const {messageId} = await client.publishJSON({
url: `${baseUrl}/${route}`,
url: `${process.env.UPSTASH_WORKFLOW_URL}/${route}`,
body: payload
});

Expand Down
21 changes: 1 addition & 20 deletions examples/workflow/nextjs/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,25 @@ import { useSearchParams } from 'next/navigation';
import { Suspense, useEffect, useState } from 'react';

function Home() {
const [baseUrl, setBaseUrl] = useState("http://localhost:3000");
const [requestBody, setRequestBody] = useState('{"date":123,"email":"[email protected]","amount":10}');
const [loading, setLoading] = useState(false);
const searchParams = useSearchParams();

// Ensure baseUrl doesn't have a trailing slash
useEffect(() => {
if (baseUrl.endsWith('/')) {
setBaseUrl(baseUrl.replace(/\/$/, ''));
}
}, [baseUrl]);

const search = searchParams.get('function');
const [route, setRoute] = useState(search ?? "path");

const routes = ['path', 'sleep', 'sleepWithoutAwait', 'northStarSimple', 'northStar', 'call'];

const handleSend = async () => {
setLoading(true);
const url = `${baseUrl}/-call-qstash`;
const url = `/-call-qstash`;
try {
const response = await fetch(url, {
headers: {
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify({
baseUrl,
route,
payload: JSON.parse(requestBody)
})
Expand All @@ -49,16 +40,6 @@ function Home() {
<div className="bg-white p-6 rounded shadow-md w-full max-w-md">
<h1 className="text-xl font-bold mb-4">Send Request</h1>

<div className="mb-4">
<label className="block text-gray-700">Base URL (replace with deployment URL):</label>
<input
type="text"
value={baseUrl}
onChange={(e) => setBaseUrl(e.target.value)}
className="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
/>
</div>

<div className="mb-4">
<label className="block text-gray-700">Route:</label>
<select
Expand Down
22 changes: 2 additions & 20 deletions examples/workflow/nuxt/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,6 @@
<div class="bg-white p-6 rounded shadow-md w-full max-w-md">
<h1 class="text-xl font-bold mb-4">Send Request</h1>

<div class="mb-4">
<label class="block text-gray-700">Base URL deployment URL:</label>
<input
v-model="baseUrl"
type="text"
class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
/>
</div>

<div class="mb-4">
<label class="block text-gray-700">Route:</label>
<select
Expand Down Expand Up @@ -48,32 +39,23 @@
<script setup>
import { ref } from 'vue';
const baseUrl = ref('http://localhost:3000');
const requestBody = ref('{"date":123,"email":"[email protected]","amount":10}');
const loading = ref(false);
const route = ref('path');
const routes = ['path', 'sleep', 'sleepWithoutAwait', 'northStarSimple', 'northStar'];
// Ensure baseUrl doesn't have a trailing slash
watch(baseUrl, (newVal) => {
if (newVal.endsWith('/')) {
baseUrl.value = newVal.replace(/\/$/, '');
}
});
const handleSend = async () => {
loading.value = true;
const url = `${baseUrl.value}/api/callQstash`;
const url = "/api/callQstash";
try {
const response = await fetch(url, {
headers: {
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify({
baseUrl: baseUrl.value,
route: route.value,
payload: requestBody.value
payload: JSON.parse(requestBody.value)
})
});
console.log('Response:', await response.json());
Expand Down
4 changes: 2 additions & 2 deletions examples/workflow/nuxt/server/api/callQstash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { defineEventHandler, readBody } from "h3";
const client = new Client({ baseUrl: process.env.QSTASH_URL!, token: process.env.QSTASH_TOKEN! });

export default defineEventHandler(async (event: H3Event) => {
const { baseUrl, route, payload } = await readBody(event) as { baseUrl: string, route: string, payload: unknown };
const { route, payload } = await readBody(event) as { route: string, payload: unknown };

try {
const { messageId } = await client.publishJSON({
url: `${baseUrl}/api/${route}`,
url: `${process.env.UPSTASH_WORKFLOW_URL}/api/${route}`,
body: payload,
});

Expand Down
4 changes: 2 additions & 2 deletions examples/workflow/solidjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"private": true,
"type": "module",
"scripts": {
"dev": "vinxi dev",
"dev": "vinxi dev --port 3001",
"build": "vinxi build",
"start": "vinxi start"
"start": "vinxi start --port 3001"
},
"devDependencies": {
"autoprefixer": "^10.4.19",
Expand Down
4 changes: 2 additions & 2 deletions examples/workflow/solidjs/src/routes/-call-qstash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ const client = new Client({ baseUrl: process.env.QSTASH_URL!, token: process.env

export const POST: APIHandler = async (event: APIEvent) => {
try {
const { baseUrl, route, payload } = await event.request.json();
const { route, payload } = await event.request.json();

const { messageId } = await client.publishJSON({
url: `${baseUrl}/${route}`,
url: `${process.env.UPSTASH_WORKFLOW_URL}/${route}`,
body: payload
});

Expand Down
24 changes: 2 additions & 22 deletions examples/workflow/solidjs/src/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,24 @@
import { createSignal, createEffect } from 'solid-js';

const LandingPage = () => {
const [baseUrl, setBaseUrl] = createSignal("http://localhost:3000");
const [requestBody, setRequestBody] = createSignal('{"date":123,"email":"[email protected]","amount":10}');
const [route, setRoute] = createSignal("path");
const [loading, setLoading] = createSignal(false);

// Ensure baseUrl doesn't have a trailing slash
createEffect(() => {
const url = baseUrl();
if (url.endsWith('/')) {
setBaseUrl(url.replace(/\/$/, ''));
}
});

const routes = ['path', 'sleep', 'sleepWithoutAwait', 'northStarSimple', 'northStar'];

const handleSend = async () => {
setLoading(true);
const url = `${baseUrl()}/-call-qstash`;
const url = "/-call-qstash";
try {
const response = await fetch(url, {
headers: {
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify({
baseUrl: baseUrl(),
route: route(),
payload: requestBody(),
payload: JSON.parse(requestBody()),
})
});
console.log('Response:', await response.json());
Expand All @@ -44,16 +34,6 @@ const LandingPage = () => {
<div className="bg-white p-6 rounded shadow-md w-full max-w-md">
<h1 className="text-xl font-bold mb-4">Send Request</h1>

<div className="mb-4">
<label className="block text-gray-700">Base URL (replace with deployment URL):</label>
<input
type="text"
value={baseUrl()}
onInput={(e) => setBaseUrl(e.currentTarget.value)}
className="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
/>
</div>

<div className="mb-4">
<label className="block text-gray-700">Route:</label>
<select
Expand Down
22 changes: 2 additions & 20 deletions examples/workflow/sveltekit/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,24 @@
import { page } from '$app/stores';
import { writable } from 'svelte/store';
let baseUrl = writable("http://localhost:3000");
let requestBody = writable('{"date":123,"email":"[email protected]","amount":10}');
let loading = writable(false);
let route = writable('path');
// Ensure baseUrl doesn't have a trailing slash
baseUrl.subscribe(value => {
if (value.endsWith('/')) {
baseUrl.set(value.replace(/\/$/, ''));
}
});
const routes = ['path', 'sleep', 'sleepWithoutAwait', 'northStarSimple', 'northStar'];
const handleSend = async () => {
loading.set(true);
const url = `${$baseUrl}/-call-qstash`;
const url = "/-call-qstash";
try {
const response = await fetch(url, {
headers: {
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify({
baseUrl: $baseUrl,
route: $route,
payload: $requestBody
payload: JSON.parse($requestBody)
})
});
console.log('Response:', await response.json());
Expand All @@ -45,15 +36,6 @@
<div class="bg-white p-6 rounded shadow-md w-full max-w-md">
<h1 class="text-xl font-bold mb-4">Send Request</h1>

<div class="mb-4">
<label class="block text-gray-700">Base URL (replace with deployment URL):</label>
<input
type="text"
bind:value={$baseUrl}
class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
/>
</div>

<div class="mb-4">
<label class="block text-gray-700">Route:</label>
<select
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ const client = new Client({
});

export const POST: RequestHandler = async ({ request }) => {
const { baseUrl, route, payload } = await request.json() as { baseUrl: string, route: string, payload: unknown };
const { route, payload } = await request.json() as { route: string, payload: unknown };

try {
const { messageId } = await client.publishJSON({
url: `${baseUrl}/${route}`,
url: `${env.UPSTASH_WORKFLOW_URL}/${route}`,
body: payload
});

Expand Down
1 change: 0 additions & 1 deletion src/client/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ export const formatWorkflowError = (error: unknown): FailureFunctionPayload => {
? {
error: error.name,
message: error.message,
stack: error.stack,
}
: {
error: "Error",
Expand Down
Loading

0 comments on commit 7ac5f5d

Please sign in to comment.