New Candid Version and Catching Send Failures: Motoko Updates

Motoko Biweekly Update Part 6!

Hi Motoko Devs!

Welcome to the latest Motoko update post. Note that we will be making these posts on a biweekly schedule going forward.

If you missed the last update post from the Motoko team, check it out here! Last time we talked about ongoing efforts with improving package management in the Motoko ecosystem, and a review of code blocks as a language feature.

Today we’ll be talking about a new language feature that lets you catch send errors, and a beta release of Candid! Bonus section about a podcast on designing languages for smart contract development.

Catch Your Errors from Message Sends: Motoko 0.8.0!

Last week, we released a new version of Motoko, including a new language feature that lets you catch message send failures.

Previously, when you sent a canister message that failed, your program would trap without giving you a chance to recover from the failure. These failures can happen from a lack of canister resources, typically because the outgoing message queue is full, or because the canister does not have enough cycles to pay for the call. (There are a few more cases where such an error can occur: see details here).

Instead of trapping, these errors are now thrown as an Error! Specifically, they are thrown with new ErrorCode #call_error { err_code = n }, where n is the error code returned by the underlying platform.

Thus, these errors can be caught and handled with try catch expressions, letting you recover or gracefully fail from these messages as you see fit!

New Candid: Beta Release

The languages team also just released a new beta release for Candid! Shoutout to @chenyan for taking point on this project.

The new version contains several new features, including some breaking changes:

First, Candid now lets you decode optional variant types, even if the variant tags are not the same, allowing upgrading variant types without breaking the client code.

The deserializer also now only performs subtype checks for reference types, which brings it into full conformity to Candid spec 1.4. The same spec is also implemented in Motoko version 0.8.0, which we released last week.

For any Rust developers out there, the Rust Candid implementation also included major improvements, including major optimizations in deserialization time and canister binary size.

The beta release is up on Please let us know of any bugs you come across before the full release!

Bonus a16z Podcast: Smart Contract Language Design

Last week, there was a podcast episode released by Andreessen Horowitz about designing languages to write smart contracts: a very relevant topic for this audience!

You can find it here: Programming Languages & Crypto - web3 with a16z crypto | Podcast on Spotify

The episode talks about the differences in challenges between Web2 and Web3 programming, and how to design languages that accommodate those differences. Personally, I found it insightful so I thought I’d share it here :slight_smile: Shoutout to @diegop for sharing this podcast with our team.

Till next time!

– DFINITY Languages team


Can you give a concrete example?


As an example, we have a function that returns opt variant { Type1; Type2 }. And we want to extend the variant tag to opt variant { Type1; Type2; Type3 }. This was not allowed in the old candid library, or we have to upgrade both the server and client code at the same time.

With the new Candid version, you can do this safely without updating the client code: When the client receives Type1 or Type2, existing code already covers that; when the client receives Type3, the value becomes null, which will be handled by the null case. No client code update is necessary unless the client code needs to handle the new Type3 variant.


Nice summary @kentosugama! Wearing my release manager hat, I should point out that version 0.8.1 was rolled out last week (containing some significant bugfixes) and it is scheduled for inclusion into the dfx 0.14 betas.

Also the 0.8 version bump should remind you to carefully consider the breaking nature of some of the new features. E.g. if you are not interested in catching send errors, you can revert to previous behaviour using a compiler flag. Also, please be aware that multiple sends from one message can result in some being egressed, but not all. Be sure to consult the release notes if you are in the bulk send business (the linked PRs as well!). Now is the time to improve your understanding of this highly desired feature and its implications.