`, for example, `contacts/create.liquid`.
-
-Commands are designed to be easily executed as background jobs [heavy commands - external API call, expensive operations computations, reports]. Each command might produce an [Event](https://github.com/Platform-OS/pos-module-core?tab=readme-ov-file#events).
-
-## Set up a Build Command
-
-As the next step, we want to use a build command in the `app/lib/commands/contacts/create/build.liquid` file.
-
-The build command is an essential part of the data processing workflow. It allows you to normalize and prepare data before it is stored or used further in your application. By defining a build command, you can manipulate incoming data, perform validations, and ensure the data meets your application's requirements. This is especially useful for tasks like cleaning up user input, setting default values, and enforcing data consistency.
-
-Build commands are defined in Liquid templates and typically involve transforming and returning JSON objects. This process ensures that your data is well-structured and ready for subsequent operations or storage.
-
-To set up a build command, you don’t need to write the code from scratch. Let’s use the dummy build command from the [core module documentation](https://github.com/Platform-OS/pos-module-core?tab=readme-ov-file#build).
-
-Here's the dummy build command from the core module documentation:
-
-{% raw %}
-```liquid
-{% parse_json data %}
- {
- "title": {{ object.title | downcase | json }},
- "uuid": {{ object.uuid | json }},
- "c__score": 0
- }
-{% endparse_json %}
-
-{% liquid
- if data['uuid'] == blank
- hash_assign data["uuid"] = '' | uuid | json
- endif
-
- return data
-%}
-```
-{% endraw %}
-
-Copy this code into your `app/lib/commands/contacts/create/build.liquid` file.
-
-## Customize the Build Command
-
-Now, we will modify the build command to suit our needs. In the build phase, you normalize the parameters, ensuring you only take what's relevant and perform any necessary transformations. The goal is to clean up and prepare the contact data (email and body) before further processing.
-
-For example, you want to ensure that the email is always in lowercase:
-
-#### app/lib/commands/contacts/create/build.liquid
-
-{% raw %}
-```liquid
-{% parse_json contact %}
- {
- "email": {{ object.email | downcase | json }},
- "body": {{ object.body | json }}
- }
-{% endparse_json %}
-
-{% liquid
- return contact
-%}
-```
-{% endraw %}
-
-The `parse_json contact` tag parses the JSON object (email and body) into a variable named `contact`.
-
-Inside the JSON object, we transform `object.email` to lowercase and ensure it is properly formatted as JSON.
-
-Every function needs to `return` an object. In this case, the function takes user parameters, processes them (downcasing the email), and returns an object with the email and body properties.
-
-## Invoking the function
-
-To process the contact data using the build command, we need to invoke the function inside the `/app/lib/commands/contacts/create.liquid` file:
-
-Here's the code snippet for invoking the function:
-
-#### app/lib/commands/contacts/create.liquid
-
-{% raw %}
-```liquid
-{% function contact = 'commands/contacts/create/build', object: object %}
-```
-{% endraw %}
-
-This line of code will call the build command, passing the `object` containing the `email` and `body` parameters to it. The build command will then process these parameters and return a normalized `contact` object.
-
-We used the `function` tag to specify the path to the build command partial. Remember, you can use LSP to autocomplete paths, so you don’t need to type them manually. In our example, the path leads to the `app/lib/commands/contacts/create/build.liquid` file.
-
-You also need to pass the `object` that you defined earlier in your `/app/views/pages/contacts/create.liquid` file, which is `object`.
-
-You might notice that LSP complains that the `contact` variable is never used. This is true for now, and we will address it in later steps.
-
-### Using the `log` tag for debugging
-
-The `log` tag is a basic and effective way to debug your platformOS application. Here's how to use it in your `app/lib/commands/contacts/create.liquid` file:
-
-#### app/lib/commands/contacts/create.liquid
-
-{% raw %}
-```liquid
-{% function contact = 'commands/contacts/create/build', object: object %}
-{% log contact, type: 'result of invoking build' %}
-
-{% return contact %}
-```
-{% endraw %}
-
-`contact`: this is the variable containing the processed object. It includes the `email` and `body` parameters, with `email` being downcased.
-
-`type: 'result of invoking build'`: this provides a label for the log entry, making it easier to identify in the logs.
-
-## Accessing logs
-
-To view your logs, you need to use the pos-cli GUI.
-
-To start the GUI, in your command line, run:
-
-
-pos-cli gui serve --sync staging
-
-
-{% include 'alert/note', content: 'Replace `staging` with the environment name you want to develop on. To list all available environments use `pos-cli env list`. Refer to the [platformOS documentation](/developer-guide/pos-cli/manage-database-using-pos-cli-gui.liquid#starting-the-gui) for detailed instructions on starting the GUI.' %}
-
-**Note**
-Replace `staging` with the environment name you want to develop on. To list all available environments use `pos-cli env list`.
-Refer to the [platformOS documentation](/developer-guide/pos-cli/manage-database-using-pos-cli-gui.liquid#starting-the-gui) for detailed instructions on starting the GUI.
-
-After starting the GUI, you will see output similar to:
-
-
- [07:23:19] Connected to https://contactus.staging.oregon.platform-os.com/
- [07:23:19] Admin: http://localhost:3333
- [07:23:19] ---
- [07:23:19] GraphiQL IDE: http://localhost:3333/gui/graphql
- [07:23:19] Liquid evaluator: http://localhost:3333/gui/liquid
- [07:23:19] Instance Logs: http://localhost:3333/logs
- [07:23:20] [Sync] Synchronizing changes to: https://contactus.staging.oregon.platform-os.com/
-
-
-Open your browser and go to [http://localhost:3333/logs](http://localhost:3333/logs) to view the logs:
-
-{% # TODO: check size %}
-
-
-Alternatively, you can use the CLI to render the logs by running the following command:
-
-
-pos-cli logs staging
-
-
-{% # TODO: check size %}
-
-
-## Example of introducing a syntax error
-
-Using the `log` tag effectively helps in diagnosing problems and ensuring your application runs smoothly.
-If you encounter a syntax error, such as an unnecessary comma, you can debug it by viewing the logs.
-For testing purposes, let's add an extra comma after `"body"` in the `app/lib/commands/contacts/create/build.liquid` file:
-
-#### app/lib/commands/contacts/create/build.liquid
-
-{% raw %}
-```liquid
-{% parse_json contact %}
- {
- "email": {{ object.email | downcase | json }},
- "body": {{ object.body | json }},
- }
-{% endparse_json %}
-
-{% liquid
- return contact
-%}
-```
-{% endraw %}
-
-Now, with this unnecessary comma added, submit the form with test data.
-
-When you introduce an error like this and then access the logs at http://localhost:3333/logs, you will see a Liquid error indicating the issue. This helps you identify and correct syntax errors.
-
-{% # TODO: check size %}
-
-
-Now, remove the extra comma and continue our task.
-
-#### app/lib/commands/contacts/create/build.liquid
-
-{% raw %}
-```liquid
-{% parse_json contact %}
- {
- "email": {{ object.email | downcase | json }},
- "body": {{ object.body | json }}
- }
-{% endparse_json %}
-
-{% liquid
- return contact
-%}
-```
-{% endraw %}
-
-{% render 'alert/next', content: 'Displaying Data', url: '/get-started/contact-us-tutorial/displaying-data' %}
+{% render 'alert/next', content: 'Using the Build Command', url: '/get-started/contact-us-tutorial/using-the-build-command' %}
\ No newline at end of file
diff --git a/app/views/pages/get-started/contact-us-tutorial/using-the-build-command.liquid b/app/views/pages/get-started/contact-us-tutorial/using-the-build-command.liquid
new file mode 100644
index 000000000..d9f44917f
--- /dev/null
+++ b/app/views/pages/get-started/contact-us-tutorial/using-the-build-command.liquid
@@ -0,0 +1,93 @@
+---
+metadata:
+ title: Using the Build Command
+ description: Follow these step-by-step tutorials to build a Contact Us form on platformOS
+converter: markdown
+---
+
+As the next step, we want to use a build command in the `app/lib/commands/contacts/create/build.liquid` file.
+
+The build command is an essential part of the data processing workflow. It allows you to normalize and prepare data before it is stored or used further in your application. By defining a build command, you can manipulate incoming data, perform validations, and ensure the data meets your application's requirements. This is especially useful for tasks like cleaning up user input, setting default values, and enforcing data consistency.
+
+Build commands are defined in Liquid templates and typically involve transforming and returning JSON objects. This process ensures that your data is well-structured and ready for subsequent operations or storage.
+
+## Set up a Build Command
+
+To set up a build command, you don’t need to write the code from scratch. Let’s use the dummy build command from the [core module documentation](https://github.com/Platform-OS/pos-module-core?tab=readme-ov-file#build).
+
+Here's the dummy build command from the core module documentation:
+
+{% raw %}
+```liquid
+{% parse_json data %}
+ {
+ "title": {{ object.title | downcase | json }},
+ "uuid": {{ object.uuid | json }},
+ "c__score": 0
+ }
+{% endparse_json %}
+
+{% liquid
+ if data['uuid'] == blank
+ hash_assign data["uuid"] = '' | uuid | json
+ endif
+
+ return data
+%}
+```
+{% endraw %}
+
+Copy this code into your `app/lib/commands/contacts/create/build.liquid` file.
+
+## Customize the Build Command
+
+Now, we will modify the build command to suit our needs. In the build phase, you normalize the parameters, ensuring you only take what's relevant and perform any necessary transformations. The goal is to clean up and prepare the contact data (email and body) before further processing.
+
+For example, you want to ensure that the email is always in lowercase:
+
+#### app/lib/commands/contacts/create/build.liquid
+
+{% raw %}
+```liquid
+{% parse_json contact %}
+ {
+ "email": {{ object.email | downcase | json }},
+ "body": {{ object.body | json }}
+ }
+{% endparse_json %}
+
+{% liquid
+ return contact
+%}
+```
+{% endraw %}
+
+The `parse_json contact` tag parses the JSON object (email and body) into a variable named `contact`.
+
+Inside the JSON object, we transform `object.email` to lowercase and ensure it is properly formatted as JSON.
+
+Every function needs to `return` an object. In this case, the function takes user parameters, processes them (downcasing the email), and returns an object with the email and body properties.
+
+## Invoking the function
+
+To process the contact data using the build command, we need to invoke the function inside the `/app/lib/commands/contacts/create.liquid` file:
+
+Here's the code snippet for invoking the function:
+
+#### app/lib/commands/contacts/create.liquid
+
+{% raw %}
+```liquid
+{% function contact = 'commands/contacts/create/build', object: object %}
+```
+{% endraw %}
+
+This line of code will call the build command, passing the `object` containing the `email` and `body` parameters to it. The build command will then process these parameters and return a normalized `contact` object.
+
+We used the `function` tag to specify the path to the build command partial. Remember, you can use LSP to autocomplete paths, so you don’t need to type them manually. In our example, the path leads to the `app/lib/commands/contacts/create/build.liquid` file.
+
+You also need to pass the `object` that you defined earlier in your `/app/views/pages/contacts/create.liquid` file, which is `object`.
+
+You might notice that LSP complains that the `contact` variable is never used. This is true for now, and we will address it in later steps.
+
+{% render 'alert/next', content: 'Using the log Tag for Debugging', url: '/get-started/contact-us-tutorial/using-the-log-tag' %}
\ No newline at end of file
diff --git a/app/views/pages/get-started/contact-us-tutorial/displaying-data.liquid b/app/views/pages/get-started/contact-us-tutorial/using-the-check-command.liquid
similarity index 88%
rename from app/views/pages/get-started/contact-us-tutorial/displaying-data.liquid
rename to app/views/pages/get-started/contact-us-tutorial/using-the-check-command.liquid
index bddf7f7ef..030126718 100644
--- a/app/views/pages/get-started/contact-us-tutorial/displaying-data.liquid
+++ b/app/views/pages/get-started/contact-us-tutorial/using-the-check-command.liquid
@@ -1,23 +1,10 @@
---
metadata:
- title: Displaying Data
+ title: Using the Check Command
description: Follow these step-by-step tutorials to build a Contact Us form on platformOS
converter: markdown
---
-{% # TODO: check size %}
-
-
-Now, if you fill in the form and there are no errors in the logs, you can see that nothing is rendered. This is expected as we haven't instructed the system to display anything yet.
-
-
-In platformOS, you can display data using double curly brackets `{% raw %}{{ }}{% endraw %}` for output, or dedicated tags like `{% raw %}{% print %}{% endraw %}` and `{% raw %}{% echo %}{% endraw %}`.
-
-- **Double Curly Brackets `{% raw %}{{ }}{% endraw %}`**: Used for rendering variables directly in your templates.
-- **`{% print %}`**: Outputs content to the template and is often used for debugging. Read our documentation about [print](https://documentation.platformos.com/api-reference/liquid/platformos-tags#print).
-- **`{% echo %}`**: Similar to `print`, but with subtle differences in context handling. Read our documentation about [echo](https://documentation.platformos.com/api-reference/liquid/theme#echo).
-
-
## Invoke the Check Command
We have our build command set up, so the next step is to invoke it in the `app/lib/commands/contacts/create.liquid` file:
diff --git a/app/views/pages/get-started/contact-us-tutorial/using-the-log-tag.liquid b/app/views/pages/get-started/contact-us-tutorial/using-the-log-tag.liquid
new file mode 100644
index 000000000..0dd81f547
--- /dev/null
+++ b/app/views/pages/get-started/contact-us-tutorial/using-the-log-tag.liquid
@@ -0,0 +1,134 @@
+---
+metadata:
+ title: Using the log Tag for Debugging
+ description: Follow these step-by-step tutorials to build a Contact Us form on platformOS
+converter: markdown
+---
+
+When building applications on platformOS, effective logging and error handling are important for quickly spotting and fixing issues. Seeing what your application is doing and catching errors as they occur can save you both time and frustration.
+
+{% include 'alert/tutorial', content: 'Before continuing with the Contact Us form, please read about [Error Handling and Troubleshooting](/get-started/error-handling) in the Getting Started section!' %}
+
+In this part of the tutorial, we’ll dive into using the [log](/api-reference/liquid/platformos-tags#log) tag, a simple yet powerful tool for debugging your platformOS application. By adding logging to your workflow, you’ll get valuable insights into how your application is performing and be able to diagnose problems more easily.
+
+Here’s how to implement logging in your `app/lib/commands/contacts/create.liquid` file:
+
+#### app/lib/commands/contacts/create.liquid
+
+{% raw %}
+```liquid
+{% function contact = 'commands/contacts/create/build', object: object %}
+{% log contact, type: 'result of invoking build' %}
+
+{% return contact %}
+```
+{% endraw %}
+
+**Explanation:**
+
+| Variable | Description |
+|----------|----------------------------------------------------------------------------------------------|
+| `contact` | This is the variable containing the processed object. It includes the `email` and `body` parameters, with `email` being downcased. |
+| `type: 'result of invoking build'` | This provides a label for the log entry, making it easier to identify in the logs. |
+
+## Accessing logs
+
+To view your logs, you need to use the pos-cli GUI.
+
+To start the GUI, in your command line, run:
+
+
+pos-cli gui serve --sync staging
+
+
+{% include 'alert/note', content: 'Replace `staging` with the environment name you want to develop on. To list all available environments use `pos-cli env list`. Refer to the [platformOS documentation](/developer-guide/pos-cli/manage-database-using-pos-cli-gui.liquid#starting-the-gui) for detailed instructions on starting the GUI.' %}
+
+After starting the GUI, you will see output similar to:
+
+
+ [07:23:19] Connected to https://contactus.staging.oregon.platform-os.com/
+ [07:23:19] Admin: http://localhost:3333
+ [07:23:19] ---
+ [07:23:19] GraphiQL IDE: http://localhost:3333/gui/graphql
+ [07:23:19] Liquid evaluator: http://localhost:3333/gui/liquid
+ [07:23:19] Instance Logs: http://localhost:3333/logs
+ [07:23:20] [Sync] Synchronizing changes to: https://contactus.staging.oregon.platform-os.com/
+
+
+Open your browser and go to [http://localhost:3333/logs](http://localhost:3333/logs) to view the logs:
+
+{% # TODO: check size %}
+
+
+Alternatively, you can use the CLI to render the logs by running the following command:
+
+
+pos-cli logs staging
+
+
+{% # TODO: check size %}
+
+
+## Example of introducing a syntax error
+
+Using the `log` tag effectively helps in diagnosing problems and ensuring your application runs smoothly.
+If you encounter a syntax error, such as an unnecessary comma, you can debug it by viewing the logs.
+For testing purposes, let's add an extra comma after `"body"` in the `app/lib/commands/contacts/create/build.liquid` file:
+
+#### app/lib/commands/contacts/create/build.liquid
+
+{% raw %}
+```liquid
+{% parse_json contact %}
+ {
+ "email": {{ object.email | downcase | json }},
+ "body": {{ object.body | json }},
+ }
+{% endparse_json %}
+
+{% liquid
+ return contact
+%}
+```
+{% endraw %}
+
+Now, with this unnecessary comma added, submit the form with test data.
+
+When you introduce an error like this and then access the logs at http://localhost:3333/logs, you will see a Liquid error indicating the issue. This helps you identify and correct syntax errors.
+
+{% # TODO: check size %}
+
+
+Now, remove the extra comma and continue our task.
+
+#### app/lib/commands/contacts/create/build.liquid
+
+{% raw %}
+```liquid
+{% parse_json contact %}
+ {
+ "email": {{ object.email | downcase | json }},
+ "body": {{ object.body | json }}
+ }
+{% endparse_json %}
+
+{% liquid
+ return contact
+%}
+```
+{% endraw %}
+
+## Display Data
+
+Now, if you fill in the form and there are no errors in the logs, you can see that nothing is rendered. This is expected as we haven't instructed the system to display anything yet.
+
+{% # TODO: check size %}
+
+
+In platformOS, you can display data using double curly brackets `{% raw %}{{ }}{% endraw %}` for output, or dedicated tags like `{% raw %}{% print %}{% endraw %}` and `{% raw %}{% echo %}{% endraw %}`.
+
+- **Double Curly Brackets `{% raw %}{{ }}{% endraw %}`**: Used for rendering variables directly in your templates.
+- **`{% raw %}{% print %}{% endraw %}`**: Outputs content to the template and is often used for debugging. Read our documentation about [print](https://documentation.platformos.com/api-reference/liquid/platformos-tags#print).
+- **`{% raw %}{% echo %}{% endraw %}`**: Similar to `print`, but with subtle differences in context handling. Read our documentation about [echo](https://documentation.platformos.com/api-reference/liquid/theme#echo).
+
+{% render 'alert/next', content: 'Using the Check Command', url: '/get-started/contact-us-tutorial/using-the-check-command' %}
\ No newline at end of file
diff --git a/app/views/pages/get-started/contact-us-tutorial/using-validators.liquid b/app/views/pages/get-started/contact-us-tutorial/using-validators.liquid
index 0709d8509..e2e1e4f6b 100644
--- a/app/views/pages/get-started/contact-us-tutorial/using-validators.liquid
+++ b/app/views/pages/get-started/contact-us-tutorial/using-validators.liquid
@@ -69,8 +69,10 @@ You might notice that the LSP is complaining that the `allow_blank` argument is
return object
%}
+```
{% endraw %}
+
The `allow_blank` argument in the validation function controls whether the field can be empty. Setting `allow_blank: false` means that if the body field is present, it must meet the specified length constraints (between 10 and 200 characters).
This means:
diff --git a/app/views/pages/get-started/error-handling.liquid b/app/views/pages/get-started/error-handling.liquid
new file mode 100644
index 000000000..2ee944275
--- /dev/null
+++ b/app/views/pages/get-started/error-handling.liquid
@@ -0,0 +1,108 @@
+---
+metadata:
+ title: Error Handling and Troubleshooting
+ description: Follow these step-by-step tutorials to build a Contact Us form on platformOS
+converter: markdown
+---
+
+When building applications with platformOS, encountering errors is a part of the journey. But don’t worry—understanding how to troubleshoot and handle errors can make your development process much smoother. This part of the tutorial will guide you through accessing logs and effectively debugging your application to resolve common issues.
+
+## Why Error Handling is Important
+
+{% # TODO: check size %}
+
+
+Imagine you've just implemented a new feature, and when you try it out, you encounter a 500 error. It can be frustrating, especially if you're not sure what went wrong. That's why learning how to access logs and interpret error messages is so important. Logs provide valuable insights into what’s happening behind the scenes, allowing you to identify issues quickly.
+
+## Accessing Logs
+
+To start troubleshooting, you'll need to view your logs. The pos-cli makes this easy! Here’s how to access your logs using the pos-cli GUI:
+
+### Start the GUI
+
+Open your command line and run:
+
+
+pos-cli gui serve --sync staging
+
+
+{% include "alert/note", content: "Replace `staging` with the environment you're working on. To view all available environments, use `pos-cli env list`." %}
+
+### Open the Logs
+
+After starting the GUI, you’ll see output that includes a link to your logs. Open your browser and go to [http://localhost:3333/logs](http://localhost:3333/logs) to view them.
+
+{% # TODO: check size %}
+
+
+### Use the CLI
+
+Alternatively, you can check the logs using the command line. Run the following command:
+
+
+pos-cli logs staging
+
+
+{% # TODO: check size %}
+
+
+## Common Errors
+
+While developing your application, you may encounter several types of errors. Here are some common ones and how to troubleshoot them:
+
+### Liquid Errors
+
+These are often due to syntax mistakes in your Liquid code. For example, if you add an extra comma, you might see an error in the logs like this:
+
+```plaintext
+[2024-05-29 07:16:29.566Z] - Liquid error: "Liquid error: parse_json filter error: Invalid JSON: expected hash key..."
+```
+
+To resolve this, check your Liquid templates for typos or syntax errors, and refer to the logs for clues.
+
+## Debugging with Logs
+
+Using the [log tag](/api-reference/liquid/platformos-tags#log) helps you identify and fix problems. Here’s how to make the most of your logs during the debugging process:
+
+### Add Logging Statements
+
+You can add logging to your commands to capture important information. For example, in your `create.liquid` file, you might log whether the data passed validation:
+
+{% raw %}
+ ```liquid
+ {% if contact_after_validation.valid %}
+ {% log "Valid!" %}
+ {% else %}
+ {% log "Not valid!" %}
+ {% endif %}
+ ```
+{% endraw %}
+
+
+### Analyze Log Output
+
+After introducing logging statements, check your logs again. If there’s an error, the logs will indicate what went wrong, helping you understand the issue quickly.
+
+## Example: Debugging a Syntax Error using Logs
+
+Imagine you accidentally introduce a syntax error by adding an unnecessary comma in your code. This is a common mistake that can lead to issues. For example, in your `build.liquid` file, you might have an extra comma:
+
+{% raw %}
+```liquid
+{% parse_json contact %}
+ {
+ "email": {{ object.email | downcase | json }},
+ "body": {{ object.body | json }},
+ }
+{% endparse_json %}
+```
+{% endraw %}
+
+When you submit a form with this error, the logs will reveal a Liquid error indicating a parsing issue:
+
+{% # TODO: check size %}
+
+
+To resolve this, remove the extra comma from the code. After fixing it and resubmitting the form, the log should now show successful validation, reflecting that the error has been addressed.
+
+{% render 'alert/next', content: 'Error Handling and Troubleshooting', url: '/get-started/error-handling' %}
\ No newline at end of file
diff --git a/app/views/partials/shared/nav/get-started.liquid b/app/views/partials/shared/nav/get-started.liquid
index 54afe221a..762f34c99 100644
--- a/app/views/partials/shared/nav/get-started.liquid
+++ b/app/views/partials/shared/nav/get-started.liquid
@@ -24,6 +24,17 @@
+
+ Error Handling and Troubleshooting
+
+
+
Build your first app
@@ -113,7 +124,6 @@
{% include "shared/nav/link", href: "/get-started/contact-us-tutorial/building-the-ui#using-path-to-the-file-as-default-route", text: "Using Path to the File as Default Route" %}
{% include "shared/nav/link", href: "/get-started/contact-us-tutorial/building-the-ui#deploy-and-check", text: "Deploy and check" %}
-
@@ -178,30 +188,45 @@
-
+
Implementing Business Rules Using Commands
+
+
+
+ Using the Build Command
+
-
- Displaying Data
+
+ Using the log Tag for Debugging
+
+
+
+
+
+ Using the Check Command