# DataWeave match/case: Replace If/Else Chains and Avoid the Missing Else Crash

I replaced a 40-line if/else chain with 4 match/case lines last month. Then I forgot the else clause and 3,000 production events backed up.

**TL;DR**
- `match/case` replaces nested if/else with value matching, guard conditions, and type dispatch
- Missing `else` clause causes runtime errors on unmatched values — unlike switch/default, there's no implicit fallthrough
- `event.type` fails — `type` is a reserved word in DataWeave, use `event."type"` with quotes
- Guard conditions (`case t if t startsWith "payment."`) handle wildcard matching

## The Problem: Growing If/Else Chains

We had an event routing flow. Orders, payments, user actions — each type needed a different processing queue:

```dataweave
if (event."type" == "order.created") { category: "ORDER", action: "PROCESS" }
else if (event."type" == "order.cancelled") { category: "ORDER", action: "REFUND" }
else if (event."type" == "payment.received") { category: "PAYMENT", action: "RECONCILE" }
else if (event."type" == "payment.refunded") { category: "PAYMENT", action: "RECONCILE" }
else if (event."type" == "user.login") { category: "CUSTOMER", action: "SYNC" }
else if (event."type" == "user.logout") { category: "CUSTOMER", action: "SYNC" }
else if (event."type" == "user.signup") { category: "CUSTOMER", action: "ONBOARD" }
else { category: "SYSTEM", action: "LOG" }
```

40 lines. Growing every sprint. Hard to read. Repetitive.

## The Fix: match/case

```dataweave
%dw 2.0
output application/json
fun routeEvent(event: Object): Object =
    event."type" match {
        case "order.created" -> ({ category: "ORDER", action: "PROCESS", priority: "NORMAL" })
        case "order.cancelled" -> ({ category: "ORDER", action: "REFUND", priority: "HIGH" })
        case eventType if eventType startsWith "payment." -> ({ category: "PAYMENT", action: "RECONCILE", priority: "HIGH" })
        else -> ({ category: "SYSTEM", action: "LOG", priority: "LOW" })
    }
---
payload.events map (event) -> routeEvent(event)
```

4 cases. Value matching for exact types. Guard condition for the payment prefix. Else for everything unexpected.

---

100 production-ready DataWeave patterns with tests: [mulesoft-cookbook on GitHub](https://github.com/shakarbisetty/mulesoft-cookbook)

---

## Trap 1: The Missing Else Clause

I deployed my first version without `else`. For 3 weeks, every event was a known type. Then an "inventory.updated" event arrived — a type I hadn't handled.

Runtime error. 3,000 events backed up in the queue before monitoring caught it.

DataWeave's match/case does NOT have implicit fallthrough. Without `else`, an unmatched value throws an exception. Unlike JavaScript's switch where falling through is the default, DataWeave requires explicit handling of every possible value.

**Rule: every match block needs an else clause. No exceptions.**

## Trap 2: Reserved Word Field Access

```dataweave
event.type    // PARSE ERROR — "type" is a reserved word
event."type"  // works — quoted field name
```

DataWeave reserves `type` as a keyword. When your JSON has a `type` field (which is extremely common in event-driven architectures), you must quote it in the selector. I spent 20 minutes debugging this the first time.

Other reserved words that break field selectors: `match`, `case`, `if`, `else`, `do`, `fun`, `var`, `type`, `input`, `output`.

## Guard Conditions: Pattern Matching with Logic

The `case eventType if eventType startsWith "payment."` syntax combines pattern matching with boolean guards:

```dataweave
event."type" match {
    case t if t startsWith "order." -> handleOrder(t)
    case t if t matches /user\.(.*)/ -> handleUser(t)
    case t if sizeOf(t) > 50 -> handleLongType(t)
    else -> handleUnknown()
}
```

You can use any boolean expression after `if`. The bound variable `t` holds the matched value for use in both the guard and the result.

## What I Do Now

1. Every match block has an else clause before deployment
2. Reserved word fields always use quoted selectors
3. New event types go into the match block proactively — I review dead-letter queue weekly
4. Code reviews flag match without else as a blocking issue

---

100 patterns with MUnit tests: [github.com/shakarbisetty/mulesoft-cookbook](https://github.com/shakarbisetty/mulesoft-cookbook)

60-second video walkthroughs: [youtube.com/@SanThaParv](https://www.youtube.com/@SanThaParv?sub_confirmation=1)
