diff --git a/docs/docs/.vuepress/config.js b/docs/docs/.vuepress/config.js
index 667c04c1edfd4..ad430d8903646 100644
--- a/docs/docs/.vuepress/config.js
+++ b/docs/docs/.vuepress/config.js
@@ -92,6 +92,7 @@ module.exports = {
"/code/nodejs/auth/",
"/code/nodejs/http-requests/",
"/code/nodejs/working-with-files/",
+ "/code/nodejs/async/",
],
},
"/code/python/",
diff --git a/docs/docs/code/nodejs/README.md b/docs/docs/code/nodejs/README.md
index 726f7a6056578..ead95b05cbdce 100644
--- a/docs/docs/code/nodejs/README.md
+++ b/docs/docs/code/nodejs/README.md
@@ -17,21 +17,18 @@ It's important to understand the core difference between Node.js and the JavaScr
## Adding a code step
1. Click the **+** button below any step of your workflow.
-2. Select the option to **Run Node.js code**.
-
-
-

-
+2. Select the option to **Run custom code**.
+3. Select the `nodejs14.x` runtime.
You can add any Node.js code in the editor that appears. For example, try:
```javascript
-defineComponent({
+export default defineComponent({
async run({ steps, $ }) {
console.log('This is Node.js code');
$.export('test', 'Some test data');
return 'Test data';
- })
+ }
});
```
@@ -44,7 +41,7 @@ You can make code steps reusable by allowing them to accept props. Instead of ha
For example, let's define a `firstName` prop. This will allow us to freely enter text from the workflow builder.
```javascript
-defineComponent({
+export default defineComponent({
props: {
firstName: {
type: 'string',
@@ -68,37 +65,43 @@ Accepting a single string is just one example, you can build a step to accept ar
[Read the props reference for the full list of options](/components/api/#props).
-## `async` function declaration
+## How Pipedream Node.js components work
-You'll notice an [`async` function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) declaration that appears when you add a new Node.js code step:
+When you add a new Node.js code step or use the examples in this doc, you'll notice a common structure to the code:
```javascript
-defineComponent({
+export default defineComponent({
async run({ steps, $ }) {
- // this Node.js code will execute when your workflow is triggered
- })
+ // this Node.js code will execute when the step runs
+ }
});
```
-This communicates a couple of key concepts:
+This defines [a Node.js component](/components/api/). Components let you:
-- Any async code within a code step [**must** be run synchronously](/workflows/steps/code/async/), using the `await` keyword or with a Promise chain, using `.then()`, `.catch()`, and related methods.
-- Pipedream passes the variables `event` and `steps` to every code step. `event` is a read-only object that contains the data that triggered your event, for example the HTTP request sent to your workflow's endpoint. `steps` is also an object, and contains the [data exported from previous steps](/workflows/steps/#step-exports) in your workflow.
+- Pass input to steps using [props](/code/nodejs/#passing-props-to-code-steps)
+- [Connect an account to a step](/connected-accounts/#from-a-code-step)
+- [Issue HTTP responses](/workflows/steps/triggers/#customizing-the-http-response)
+- Perform workflow-level flow control, like [ending a workflow early](#ending-a-workflow-early)
-If you're using [step props](/code/nodejs/#passing-props-to-code-steps) or [connect an account to a step](/connected-accounts/#from-a-code-step), they are available under `this` within the `run` function of the step.
+When the step runs, Pipedream executes the `run` method:
+
+- Any asynchronous code within a code step [**must** be run synchronously](/workflows/steps/code/async/), using the `await` keyword or with a Promise chain, using `.then()`, `.catch()`, and related methods.
+- Pipedream passes the `steps` variable to the run method. `steps` is also an object, and contains the [data exported from previous steps](/workflows/steps/#step-exports) in your workflow.
+- You also have access to the `$` variable, which gives you access to methods like `$.respond`, `$.export`, [and more](/components/api/#actions).
+
+If you're using [props](/code/nodejs/#passing-props-to-code-steps) or [connect an account to a step](/connected-accounts/#from-a-code-step), the component exposes them in the variable `this`, which refers to the current step:
```javascript
export default defineComponent({
async run({ steps, $ }) {
- // this Node.js code will execute when your workflow is triggered
-
- })
+ // `this` refers to the running component. Props, connected accounts, etc. are exposed here
+ console.log(this)
+ }
});
```
-When you use [step parameters](/code/nodejs/#passing-props-to-code-steps), Pipedream passes the `props` object (named pairs of prop key and its associated value) to the function.
-
-When you [connect an account to a step](/connected-accounts/#from-a-code-step), Pipedream passes the API keys to [`this.appName.$auths` object](/workflows/steps/code/auth/#the-auths-object) to the function.
+When you [connect an account to a step](/connected-accounts/#from-a-code-step), Pipedream exposes the auth info in the variable [`this.appName.$auth`](/workflows/steps/code/auth/#the-auths-object).
## Logs
@@ -116,7 +119,7 @@ export default defineComponent({
console.dir({
name: "Luke"
})
- })
+ }
});
```
@@ -222,7 +225,7 @@ In general, if you just need to make an HTTP request but don't care about the re
## Returning HTTP responses
-You can return HTTP responses from [HTTP-triggered workflows](/workflows/steps/triggers/#http) using the [`$respond()` function](/workflows/steps/triggers/#customizing-the-http-response).
+You can return HTTP responses from [HTTP-triggered workflows](/workflows/steps/triggers/#http) using the [`$.respond()` function](/workflows/steps/triggers/#customizing-the-http-response).
## Managing state
@@ -243,7 +246,7 @@ For more information on what functionality is available for those languages, ple
By default, Node.js steps don't have access to the database service. It needs to be injected by defining it as a `prop`.
```javascript
-defineComponent({
+export default defineComponent({
props: {
// Define that the "db" variable in our component is a database
db: "$.service.db",
@@ -251,7 +254,7 @@ defineComponent({
async run({ steps, $ }) {
// Now we can access the database at "this.db"
this.db.set("name", "Dylan")
- })
+ }
});
```
@@ -336,7 +339,7 @@ export default defineComponent({
// If the current email being passed from our webhook is already in our list, exit early
if(emails.includes(email)) {
- $.flow.exit('Already welcomed this user');
+ return $.flow.exit('Already welcomed this user');
}
// Add the current email to the list of past emails so we can detect it in the future runs
@@ -352,7 +355,7 @@ The `$.service.db` is only currently available in Node.js code steps. It is not
In addition, `$.service.db` can hold up to {{ $site.themeConfig.SERVICE_DB_SIZE_LIMIT }} per step.
-## `$end`
+## Ending a workflow early
Sometimes you want to end your workflow early, or otherwise stop or cancel the execution or a workflow under certain conditions. For example:
@@ -361,44 +364,36 @@ Sometimes you want to end your workflow early, or otherwise stop or cancel the e
- You only want to run your workflow for users in the United States. If you receive a request from outside the U.S., you don't want the rest of the code in your workflow to run.
- You may use the `user_id` contained in the event to look up information in an external API. If you can't find data in the API tied to that user, you don't want to proceed.
-**In any code step, calling the `$.flow.exit()` function will end the execution of the workflow immediately.** No remaining code in that step, and no code or destination steps below, will run for the current event.
+**In any code step, calling `return $.flow.exit()` will end the execution of the workflow immediately.** No remaining code in that step, and no code or destination steps below, will run for the current event.
```javascript
-defineComponent({
+export default defineComponent({
async run({ steps, $ }) {
- $.flow.exit();
+ return $.flow.exit();
console.log("This code will not run, since $.flow.exit() was called above it");
- })
+ }
});
```
You can pass any string as an argument to `$.flow.exit()`:
```javascript
-defineComponent({
+export default defineComponent({
async run({ steps, $ }) {
- $.end("Event doesn't have the correct schema");
- })
+ return $.flow.exit("End message");
+ }
});
```
-This message will appear in the Inspector in the **Messages** column for the event where `$.flow.exit()` was called:
-
-
-

-
-
-Like any other code, `$.flow.exit()` can be called conditionally:
-
```javascript
-defineComponent({
+export default defineComponent({
async run({ steps, $ }) {
// Flip a coin, running $.flow.exit() for 50% of events
if (Math.random() > 0.5) {
- $.flow.exit();
+ return $.flow.exit();
}
console.log("This code will only run 50% of the time");
- })
+ }
});
```
@@ -406,15 +401,9 @@ defineComponent({
[Errors](https://nodejs.org/dist/latest-v10.x/docs/api/errors.html#errors_errors) raised in a code step will stop the execution of code or destinations that follow.
-You'll see the message associated with the error in the Inspector and the code step where the error was raised.
-
-
-

-
-
## Using secrets in code
-Workflow code is private by default, but [you can make a workflow public](/public-workflows/). In either case, we recommend you don't include secrets — API keys, tokens, or other sensitive values — directly in code steps.
+Workflow code is private. Still, we recommend you don't include secrets — API keys, tokens, or other sensitive values — directly in code steps.
Pipedream supports [environment variables](/environment-variables/) for keeping secrets separate from code. Once you create an environment variable in Pipedream, you can reference it in any workflow using `process.env.VARIABLE_NAME`. The values of environment variables are private.
@@ -449,12 +438,12 @@ When you're searching for how to do something in JavaScript, some of the code yo
Many of the most basic JavaScript tutorials are geared towards writing code for a web browser to run. This is great for learning — a webpage is one of the coolest things you can build with code. We recommend starting with these general JavaScript tutorials and trying the code you learn on Pipedream:
- [JavaScript For Cats](http://jsforcats.com/)
-- [Mozilla - JavaScript First Steps](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps)
+- [Mozilla - JavaScript First Steps](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps)
- [StackOverflow](https://stackoverflow.com/) operates a programming Q&A site that typically has the first Google result when you're searching for something specific. It's a great place to find answers to common questions.
### I know how to code, but don't know JavaScript
-- [A re-introduction to JavaScript (JS tutorial)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
+- [A re-introduction to JavaScript (JS tutorial)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
- [MDN language overview](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
- [Eloquent Javascript](https://eloquentjavascript.net/)
- [Node School](https://nodeschool.io/)
diff --git a/docs/docs/code/nodejs/async/README.md b/docs/docs/code/nodejs/async/README.md
index 7d27da22325c6..b9433e91f1f6d 100644
--- a/docs/docs/code/nodejs/async/README.md
+++ b/docs/docs/code/nodejs/async/README.md
@@ -1,4 +1,4 @@
-# Running asynchronous code
+# Running asynchronous code in Node.js
If you're not familiar with asynchronous programming concepts like [callback functions](https://developer.mozilla.org/en-US/docs/Glossary/Callback_function) or [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises), see [this overview](https://eloquentjavascript.net/11_async.html).
diff --git a/docs/docs/code/nodejs/auth/README.md b/docs/docs/code/nodejs/auth/README.md
index 412e8dc370ecc..91cfcbe7f8597 100644
--- a/docs/docs/code/nodejs/auth/README.md
+++ b/docs/docs/code/nodejs/auth/README.md
@@ -20,7 +20,7 @@ export default defineComponent({
}
},
async run({ steps, $ }) {
- const web = new WebClient(this.slack.$auths.oauth_access_token)
+ const web = new WebClient(this.slack.$auth.oauth_access_token)
return await web.chat.postMessage({
text: "Hello, world!",
@@ -38,12 +38,12 @@ Now the step in the workflow builder will allow you to connect your Slack accoun
[[toc]]
-## Accessing API tokens with `this.appName.$auths`
+## Accessing connected account data with `this.appName.$auth`
In our Slack example above, we created a Slack `WebClient` using the Slack OAuth access token:
```javascript
-const web = new WebClient(this.slack.$auths.oauth_access_token);
+const web = new WebClient(this.slack.$auth.oauth_access_token);
```
Where did `this.slack` come from? Good question. It was generated by the definition we made in `props`:
@@ -62,7 +62,7 @@ export default defineComponent({
// ... rest of the Node.js step
```
-The Slack access token is generated by Pipedream, and is available to this step in the `this.slack.$auths` object:
+The Slack access token is generated by Pipedream, and is available to this step in the `this.slack.$auth` object:
```javascript
export default defineComponent({
@@ -83,18 +83,12 @@ export default defineComponent({
`this.appName.$auths` contains named properties for each account you connect to the associated step. Here, we connected Slack, so `this.slack.$auths` contains the Slack auth info (the `oauth_access_token`).
-You can view the named properties of the `this.appName.$auths` object for connected accounts next to the account connections:
-
-
-

-
-
The names of the properties for each connected account will differ with the account. Pipedream typically exposes OAuth access tokens as `oauth_access_token`, and API keys under the property `api_key`. But if there's a service-specific name for the tokens (for example, if the service calls it `server_token`), we prefer that name, instead.
To list the `this.[app name].$auths` properties available to you for a given app, run `Object.keys` on the app:
```javascript
-console.log(Object.keys(this.slack.$auths)) // Replace auths.slack with your app's name
+console.log(Object.keys(this.slack.$auth)) // Replace this.slack with your app's name
```
and run your workflow. You'll see the property names in the logs below your step.
@@ -111,11 +105,7 @@ When you search for an app in a step:
1. Click the **+** button below any step.
2. Search for the app you're looking for and select it from the list.
-3. Select the option to **Run Node.js code with [app]**.
-
-
-

-
+3. Select the option to **Use any [app] API**.
This code operates as a template you can extend, and comes preconfigured with the connection to the target app and the code for authorizing requests to the API. You can modify this code however you'd like.
diff --git a/docs/docs/code/nodejs/http-requests/README.md b/docs/docs/code/nodejs/http-requests/README.md
index 25069ca423056..1f7b3e1499703 100644
--- a/docs/docs/code/nodejs/http-requests/README.md
+++ b/docs/docs/code/nodejs/http-requests/README.md
@@ -90,7 +90,7 @@ const resp = await axios({
url: `https://jsonplaceholder.typicode.com/posts`,
data: {
name: "Luke",
- }
+ },
});
// Retrieve just the data from the response
@@ -177,21 +177,25 @@ There are many ways to make multiple HTTP requests. This code shows you a simple
```javascript
import axios from "axios";
-// We'll store each response and return them in this array
-const responses = [];
-
-for (const num of [1, 2, 3]) {
- const resp = await axios({
- method: "POST",
- url: params.url,
- data: {
- num, // Will send the current value of num in the loop
- },
- });
- responses.push(resp.data);
-}
-
-return responses;
+export default defineComponent({
+ async run({ steps, $ }) {
+ // We'll store each response and return them in this array
+ const responses = [];
+
+ for (const num of [1, 2, 3]) {
+ const resp = await axios({
+ method: "POST",
+ url: "https://example.com",
+ data: {
+ num, // Will send the current value of num in the loop
+ },
+ });
+ responses.push(resp.data);
+ }
+
+ return responses;
+ },
+});
```
This sends each HTTP request _in sequence_, one after another, and returns an array of response data returned from the URL to which you send the POST request. If you need to make requests _in parallel_, [see these docs](#send-multiple-http-requests-in-parallel).
@@ -205,10 +209,19 @@ Sometimes you'll want to make multiple HTTP requests in parallel. If one request
To make requests in parallel, you can use two techniques. By default, we recommend using [`promise.allSettled`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled), which makes all HTTP requests and returns data on their success / failure. If an HTTP request fails, all other requests will proceed.
```javascript
-import axios from "axios"
-const arr = ["https://www.example.com", "https://www.cnn.com", "https://www.espn.com"]
-const promises = arr.map(url => axios.get(url))
-return Promise.allSettled(promises)
+import axios from "axios";
+
+export default defineComponent({
+ async run({ steps, $ }) {
+ const arr = [
+ "https://www.example.com",
+ "https://www.cnn.com",
+ "https://www.espn.com",
+ ];
+ const promises = arr.map((url) => axios.get(url));
+ return Promise.allSettled(promises);
+ },
+});
```
First, we generate an array of `axios.get` requests (which are all [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)), and then call `Promise.allSettled` to run them in parallel.
@@ -216,15 +229,24 @@ First, we generate an array of `axios.get` requests (which are all [Promises](ht
When you want to stop future requests when _one_ of the requests fails, you can use [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all), instead:
```javascript
-import axios from "axios"
-const arr = ["https://www.example.com", "https://www.cnn.com", "https://www.espn.com"]
-const promises = arr.map(url => axios.get(url))
-return Promise.all(promises)
+import axios from "axios";
+
+export default defineComponent({
+ async run({ steps, $ }) {
+ const arr = [
+ "https://www.example.com",
+ "https://www.cnn.com",
+ "https://www.espn.com",
+ ];
+ const promises = arr.map((url) => axios.get(url));
+ return Promise.all(promises);
+ },
+});
```
The Mozilla docs expand on the difference between these methods, and when you may want to use one or the other:
->The `Promise.allSettled()` method returns a promise that resolves after all of the given promises have either fulfilled or rejected, with an array of objects that each describes the outcome of each promise.
+> The `Promise.allSettled()` method returns a promise that resolves after all of the given promises have either fulfilled or rejected, with an array of objects that each describes the outcome of each promise.
> It is typically used when you have multiple asynchronous tasks that are not dependent on one another to complete successfully, or you'd always like to know the result of each promise.
> In comparison, the Promise returned by `Promise.all()` may be more appropriate if the tasks are dependent on each other / if you'd like to immediately reject upon any of them rejecting.
@@ -234,17 +256,21 @@ The Mozilla docs expand on the difference between these methods, and when you ma
import axios from "axios";
import FormData from "form-data";
-const formData = new FormData();
-formData.append("name", "Luke Skywalker");
-
-const headers = formData.getHeaders();
-const config = {
- method: "POST",
- url: params.url,
- headers,
- data: formData,
-};
-return await axios(config);
+export default defineComponent({
+ async run({ steps, $ }) {
+ const formData = new FormData();
+ formData.append("name", "Luke Skywalker");
+
+ const headers = formData.getHeaders();
+ const config = {
+ method: "POST",
+ url: "https://example.com",
+ headers,
+ data: formData,
+ };
+ return await axios(config);
+ }
+});
```
[Copy this workflow](https://pipedream.com/@dylburger/send-a-multipart-form-data-request-p_WxCQRyr/edit) to run this example.
@@ -262,8 +288,8 @@ import got from "got";
// DOWNLOAD
const pipeline = promisify(stream.pipeline);
await pipeline(
- got.stream(params.downloadURL),
- fs.createWriteStream(params.filePath)
+ got.stream("https://example.com"),
+ fs.createWriteStream('/tmp/yourfile')
);
```
@@ -280,17 +306,21 @@ import axios from "axios";
import fs from "fs";
import FormData from "form-data";
-const formData = new FormData();
-formData.append("file", fs.createReadStream(params.pathToYourFile));
-const headers = formData.getHeaders();
-
-const config = {
- method: "POST",
- url: params.url,
- headers,
- data: formData,
-};
-return await axios(config);
+export default defineComponent({
+ async run({ steps, $ }) {
+ const formData = new FormData();
+ formData.append("file", fs.createReadStream('/tmp/yourfile'));
+ const headers = formData.getHeaders();
+
+ const config = {
+ method: "POST",
+ url: "https://example.com",
+ headers,
+ data: formData,
+ };
+ return await axios(config);
+ }
+});
```
[Copy this workflow](https://pipedream.com/@dylburger/stream-a-file-upload-p_6lC1d2Z/edit) to run this example.
@@ -303,17 +333,21 @@ By default, HTTP requests made from Pipedream can come from a range of IP addres
```javascript
import axios from "axios";
-
import httpsProxyAgent from "https-proxy-agent";
-const agent = new httpsProxyAgent(`http://${user}:${pass}@${host}:${port}`);
-const config = {
- method: "GET",
- url,
- httpsAgent: agent,
-};
+export default defineComponent({
+ async run({ steps, $ }) {
+ const agent = new httpsProxyAgent(`http://${user}:${pass}@${host}:${port}`);
-const resp = await axios.request(config);
+ const config = {
+ method: "GET",
+ url: "https://example.com",
+ httpsAgent: agent,
+ };
+
+ return await axios.request(config);
+ }
+});
```
**If you don't have access to an HTTP proxy, and you are a paying Pipedream customer, [reach out to our team](https://pipedream.com/support)**. We operate a proxy that you can use for HTTP requests made through Pipedream.
@@ -327,43 +361,6 @@ By default, [HTTP requests made from Pipedream can come from a large range of IP
- [Use an HTTP proxy to proxy requests](#use-an-http-proxy-to-proxy-requests-through-another-host)
- If you don't need to access the HTTP response data, you can [use `$send.http()`](/destinations/http/) to send requests from a [limited set of IP addresses](/destinations/http/#ip-addresses-for-pipedream-http-requests).
-## Forward an incoming HTTP request to another URL
-
-Often, you'll want to forward an incoming HTTP request from Pipedream to another service, with the same HTTP method, headers, body, etc. [This workflow](https://pipedream.com/@dylburger/forward-http-request-issue-http-response-p_BjC8Pp/edit) does just that.
-
-Once you **Copy** the workflow, enter the **URL** where you'd like to forward an HTTP request in the `forward_http_request` step. Every HTTP request you send to the workflow's HTTP endpoint will get forwarded to that URL.
-
-```javascript
-const config = {
- method: event.method || "POST",
- url: params.url,
-};
-
-const { query } = event;
-if (Object.keys(query).length) {
- config.params = query;
-}
-
-// Headers, removing the original Host
-const { headers } = event;
-delete headers.host;
-if (Object.keys(headers).length) {
- config.headers = headers;
-}
-
-if (event.body) config.data = event.body;
-
-return await require("@pipedreamhq/platform").axios(this, config);
-```
-
-You can modify this workflow in any way you'd like. For example, if you wanted to forward only certain types of requests, you could add another Node.js code step before the `forward_http_request` step, [ending the workflow early](/workflows/steps/code/#end) if the request doesn't contain a specific key in the HTTP payload:
-
-```javascript
-if (!event.body.myImportantData) {
- $end("myImportantData not present in HTTP payload. Exiting");
-}
-```
-
## Stream a downloaded file directly to another URL
Sometimes you need to upload a downloaded file directly to another service, without processing the downloaded file. You could [download the file](#download-a-file-to-the-tmp-directory) and then [upload it](#upload-a-file-from-the-tmp-directory) to the other URL, but these intermediate steps are unnecessary: you can just stream the download to the other service directly, without saving the file to disk.
@@ -375,18 +372,21 @@ This method is especially effective for large files that exceed the [limits of t
```javascript
import stream from "stream";
import { promisify } from "util";
-import fs from "fs";
import got from "got";
-const pipeline = promisify(stream.pipeline);
+export default defineComponent({
+ async run({ steps, $ }) {
+ const pipeline = promisify(stream.pipeline);
-await pipeline(
- got.stream(params.downloadURL),
- got.stream.post(params.uploadURL)
-);
+ await pipeline(
+ got.stream("https://example.com"),
+ got.stream.post("https://example2.com")
+ );
+ }
+});
```
-You'll be asked to provide the **Download URL** — the URL of the content you want to download — and the **Upload URL** — the place you want to upload the content to. `got` streams the content directly, downloading the file using a `GET` request and uploading it as a `POST` request.
+You'll want to replace `https://example.com` with the URL you'd like to stream data from, and replace `https://example2.com` with the URL you'd like to send the data _to_. `got` streams the content directly, downloading the file using a `GET` request and uploading it as a `POST` request.
If you need to modify this behavior, [see the `got` Stream API](https://github.com/sindresorhus/got#gotstreamurl-options).
@@ -397,15 +397,19 @@ By default, `axios` throws an error when the HTTP response code is in the 400-50
```javascript
import axios from "axios";
-const resp = await axios({
- url: "https://httpstat.us/400",
- validateStatus: () => true, // will not throw error when axios gets a 400+ status code (the default behavior)
-})
-if (resp.status >= 400) {
- this.debug = resp
- throw new Error(JSON.stringify(resp.data)) // This can be modified to throw any error you'd like
-}
-return resp
+export default defineComponent({
+ async run({ steps, $ }) {
+ const resp = await axios({
+ url: "https://httpstat.us/400",
+ validateStatus: () => true, // will not throw error when axios gets a 400+ status code (the default behavior)
+ });
+ if (resp.status >= 400) {
+ this.debug = resp;
+ throw new Error(JSON.stringify(resp.data)); // This can be modified to throw any error you'd like
+ }
+ return resp;
+ }
+});
```
See [the `axios` docs](https://github.com/axios/axios#request-config) for more details.
diff --git a/docs/docs/code/nodejs/working-with-files/README.md b/docs/docs/code/nodejs/working-with-files/README.md
index 1139555ca60fa..1bd23597bf5c9 100644
--- a/docs/docs/code/nodejs/working-with-files/README.md
+++ b/docs/docs/code/nodejs/working-with-files/README.md
@@ -25,7 +25,7 @@ defineComponent({
const { path, cleanup } = await file();
await fs.promises.appendFile(path, Buffer.from("hello, world"))
await cleanup();
- })
+ }
});
```
@@ -39,7 +39,7 @@ import fs from "fs";
defineComponent({
async run({ steps, $ }) {
return fs.readdirSync("/tmp");
- })
+ }
});
```
@@ -54,7 +54,7 @@ defineComponent({
async run({ steps, $ }) {
const files = await fs.promises.readFile('/tmp/your-file');
this.fileData = files.toString()
- })
+ }
});
```
@@ -66,7 +66,7 @@ import fs from "fs";
defineComponent({
async run({ steps, $ }) {
return await fs.promises.unlink('/tmp/your-file');
- })
+ }
});
```