DEV Community

Cover image for DataWeave match/case: Replace If/Else Chains and Avoid the Missing Else Crash
ThaSha
ThaSha

Posted on

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:

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" }
Enter fullscreen mode Exit fullscreen mode

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

The Fix: match/case

%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)
Enter fullscreen mode Exit fullscreen mode

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


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

event.type    // PARSE ERROR — "type" is a reserved word
event."type"  // works — quoted field name
Enter fullscreen mode Exit fullscreen mode

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:

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()
}
Enter fullscreen mode Exit fullscreen mode

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

60-second video walkthroughs: youtube.com/@SanThaParv

Top comments (0)