Study guide

8.2 Complex expressions & flow control with error handling

Microsoft Power Platform Developer Associate PL-400

Track your progress as you read

Finished sections get a check mark.

1 Introduction, Exam Overview & Developer Toolchain

0.1 PL-400 Exam Facts 0.2 Audience Profile & Required Developer Skills 0.3 The Power Platform Developer Toolchain 0.4 Extension-Point Map & AI in the Developer Workflow

2 Create a Technical Design

1.1 Analyzing Technical Architecture and Choosing Out-of-the-Box vs. Custom Solutions 1.2 Designing Authentication, Authorization, and Security Architecture 1.3 Deciding Where Business Logic Runs and Choosing the Right Table Type 1.4 Designing Reusable Power Apps Components and Custom Connectors 1.5 Designing Dataverse Code Components, Automations, and Integrations

3 Build Power Platform Solutions

2.1 Managing Power Platform Environments for Development 2.2 Dataverse Security Roles for Code Components, Least Privilege & Troubleshooting Operational Security 2.3 Solutions, Managing Dependencies & Solution Layers 2.4 Environment Variables & Connection References 2.5 Power Platform Pipelines & CI/CD with Power Platform Build Tools

4 Implement Power Apps Improvements

3.1 Complex Power Fx Formulas and Functions 3.2 Building Reusable Canvas Component Libraries 3.3 Invoking Power Automate Cloud Flows from a Canvas App 3.4 Troubleshooting Canvas and Model-Driven Apps with Monitor and Browser Debugging Tools 3.5 Optimizing Canvas and Model-Driven App Performance

5 Extend the User Experience

4.1 The Client API Object Model & JavaScript Form Scripting 4.2 Event Handler Registration & Navigation to Custom Pages via the Client API 4.3 Client Scripting Against the Dataverse Web API; Command Bar & Buttons with Power Fx and JavaScript 4.4 PCF Fundamentals: The Component Manifest & Lifecycle Events 4.5 Implementing PCF Component Interfaces; Device, Utility & Web API Features 4.6 Packaging, Deploying & Consuming a PCF Component

6 Extend the Platform: Dataverse Plug-ins & Custom APIs

5.1 Plug-in Fundamentals & the Event Execution Pipeline Stages 5.2 Execution Context & Implementing Business Logic in Plug-ins 5.3 Pre/Post Images & Organization Service Operations in Plug-ins 5.4 Registering Plug-ins with the Plug-in Registration Tool & Optimizing Plug-in Performance 5.5 Custom API Messages & Plug-ins That Implement a Custom API 5.6 Configuring Dataverse Business Events

7 Extend the Platform: Custom Connectors

6.1 Open API Definitions: Building and Extending a Custom Connector 6.2 Authentication and Policy Templates for Custom Connectors 6.3 Importing Definitions and Creating Connectors for Azure Services 6.4 Azure Functions in Custom Connectors and Data Transformation

8 Extend the Platform: Platform APIs & Azure Functions

7.1 Dataverse Web API Operations & OAuth Authentication 7.2 Organization Service Operations, Concurrency, Transactions & Bulk Operations 7.3 Service Protection API Limits & Retry Policies 7.4 Azure Functions for Long-Running, Scheduled & Event-Driven Workloads 7.5 Authenticating to Power Platform with Managed Identities

9 Extend the Platform: Power Automate Cloud Flows

8.1 Dataverse connector triggers/actions, trigger filters & retry policies 8.2 Complex expressions & flow control with error handling 8.3 Sensitive input/output parameters & Azure Key Vault 8.4 Reusable child flows & Microsoft Entra ID service principals

10 Develop Integrations

9.1 Publishing Dataverse Events: IServiceEndpointNotificationService & the Plug-in Registration Tool 9.2 Registering Service Endpoints: Webhooks, Azure Service Bus & Event Hub 9.3 Data Synchronization with Change Tracking & Alternate Keys 9.4 Upsert-Based Synchronization with the UpsertRequest Message

11 Exam Readiness & Practice

10.1 Cross-Domain "Where Do I Implement This?" Decision Framework 10.2 Exam-Day Strategy, PL-400 Item Styles & Study Plan

8.2 Complex expressions & flow control with error handling

Key Takeaways Explain This Topic AI

Cloud flows run on the Workflow Definition Language (WDL), whose functions span string, collection, logical, conversion, date/time, and referencing categories.

Compose stores a single computed value for reuse, variables support reassignment across a flow, and Parse JSON turns a raw payload into strongly typed dynamic content using a schema.

Apply to each runs sequentially by default but supports Concurrency Control for parallel execution up to 50 threads.

A Try/Catch/Finally pattern is built from Scope actions whose Configure run after settings determine whether Catch or Finally executes.

The Terminate action explicitly sets a flow run's status to Failed, Cancelled, or Succeeded so a handled error isn't misreported as a plain success.

Last updated: July 2026

Cloud flows are built on the Workflow Definition Language (WDL) , the JSON-based expression language underneath every visual designer canvas. Every value a flow computes dynamically — a concatenated string, a date offset, a value pulled from a prior step's output — is a WDL expression, and PL-400 candidates are expected to read and write them directly, not just click through the dynamic content picker.

Expression Categories

WDL functions fall into a handful of families:

Category Example functions Typical use

String concat() , replace() , split() , substring() , toUpper() Building composite text, parsing delimited values

Collection first() , last() , length() , union() , intersect() Working with arrays from List rows or Parse JSON

  • Logical equals() , and() , or() , not() , if() Conditional expressions written inline in a field
  • Conversion string() , int() , float() , json() , xml() Casting between types, e.g. before math operations
  • Date/time utcNow() , addDays() , formatDateTime() Scheduling logic and date-column comparisons

Referencing triggerBody() , triggerOutputs() , body('Action_name') , outputs('Action_name') , variables() , parameters() Pulling values from the trigger, a named action, a flow variable, or a flow parameter

Every expression starts with an @ prefix when embedded in raw JSON, though the visual designer hides that prefix inside its formula bar.

Compose, Variables, and Parse JSON

Three actions do a disproportionate amount of the work in complex flows:

Compose stores a computed value (a concatenated string, an if() result, a reshaped object) once so it can be referenced by name from later steps, instead of recomputing or re-copying the same expression repeatedly. It is a single assignment — cheaper than a variable when the value never needs to change.

Initialize variable / Set variable creates a named, mutable value that can be reassigned multiple times across the flow — the right choice for an accumulator inside a loop, where Compose's single-assignment model does not fit.

Parse JSON takes a raw JSON payload — typically an HTTP response or an untyped Compose output — and, using a schema (hand-written or generated from a sample payload), turns its properties into strongly typed dynamic content that appears by name in the picker for every later step, instead of forcing manual body('HTTP')?['field'] expressions.

Looping and Branching

Apply to each iterates an array (for example, the output of List rows). By default iterations run sequentially; Concurrency Control in the action's settings can be enabled to run iterations in parallel (up to 50 threads), trading strict ordering for throughput.

Condition (If) and Switch branch the flow based on an expression or a matched value, each branch containing its own set of actions.

Do until repeats a block until an expression evaluates true; it defaults to a cap of 60 iterations or a one-hour timeout, whichever comes first, both adjustable in the action's settings — a required safeguard against a runaway loop.

Error Handling with Scopes and Configure Run After

Cloud flows have no native try/catch keyword, so the standard pattern uses Scope containers combined with each action's Configure run after setting, which controls whether an action runs based on the outcome of the step(s) before it:

  • Run-after option Meaning
  • is successful Runs only if the prior action succeeded (the default)
  • has failed Runs only if the prior action failed
  • is skipped Runs only if the prior action was skipped (e.g., its own run-after condition wasn't met)
  • has timed out Runs only if the prior action exceeded its timeout

A Try/Catch/Finally pattern groups the primary logic in a Try scope, adds a Catch scope configured to run after Try has failed , and adds a Finally scope with all four run-after boxes checked so it always executes regardless of outcome — mirroring cleanup code in traditional programming.

Terminate

Inside a Catch scope, the Terminate action explicitly ends the flow run with a chosen status — Failed , Cancelled , or Succeeded — plus an optional custom error code and message. Without it, a flow whose Catch scope handles an error gracefully can be misreported in run history as "Succeeded," hiding a real failure from monitoring; Terminate lets the developer set the status that actually reflects what happened.

A Practical Error-Handling Pattern

A production-grade Catch scope rarely calls Terminate alone. A typical sequence inside Catch is: (1) a Compose action that pulls the failed action's error details out of the Try scope's outputs using an expression such as result('Try_Scope') , which returns the status and error of every action inside that scope; (2) a notification action (an email or a Teams message to an operations channel) that surfaces the composed error details to a human; and (3) a Terminate action that ends the run as Failed with a message summarizing what went wrong. This turns an otherwise silent failure into an actionable alert instead of a run that quietly disappears into history.

Nested Scopes

Scopes can be nested inside one another, which is useful for isolating error handling around a specific sub-process without wrapping the entire flow in one enormous Try block. For example, a flow that processes several unrelated integrations can give each integration its own Try/Catch pair, so a failure in one integration is contained and reported without stopping the others — a design consideration the exam frames as "flow control actions including error handling" rather than a single global try/catch.