Jump to content

Wikifunctions:Status updates/2025-12-11

From Wikifunctions
Wikifunctions Status updates Translate

Abstract Wikipedia via mailing list Volunteer Response Team Abstract Wikipedia on IRC Wikifunctions on Telegram Wikifunctions on Mastodon Wikifunctions on Twitter Wikifunctions on Facebook Wikifunctions on YouTube Wikifunctions website Translate

How to write better error messages

Over the past two quarters, we have taken a big step forward in enabling community control over function failures. Last quarter we shipped a number of features around handling errors from both code and composition implementations. This quarter, we focused on something just as important: documenting how it works, so everyone can use these features with confidence.

The result is a smoother, configurable, translatable, and more community-manageable approach to errors in Wikifunctions, and we're excited to finally share it.

Why focus on errors?

Error labels and their relevant information are now fully translatable

Errors are always an important part of programming. Till now, errors could be thrown from code implementations with native JavaScript throw new Error() or raise Exception() in Python. But for a collaborative multilingual project like ours, errors need to be more than just static text. They need to be:

  • Manageable by the community;
  • Testable, just like any other output;
  • Translatable, so that everyone around the world can see meaningful messages; and
  • Structured, so compositions can use them.

How to throw errors from code implementations?

With the new backend features, now throwing errors is quite simple from both code implementations and compositions. Any code implementation (either JavaScript or Python) can now make use of the Wikifunctions.Error() method to end the execution with a wanted failure. Wikifunctions.Error() takes two parameters:

  • A first one with the ZID of the Error Type (Z50) to be thrown
  • A second one with a list of string arguments to build the error and provide useful information about what caused the failure.

So, for example, when implementing first matching representation string from lexeme, it becomes useful to throw different errors depending on the input values, so:

  • If the input lexeme has no forms, we can throw an error of type The lexeme doesn't have forms, with the lexeme ID as argument, and
  • If the input lexeme has no forms that match any of the input grammatical features, we can throw an error of type Lexeme lacks compatible representations, with the lexeme ID and the requested grammatical features.

You can see this great example of error usage in the JavaScript implementation of Z19241, or read more details and examples guide about Throwing errors from code implementations.

What about compositions?

Handling errors in compositions brings a different set of challenges. Unlike code implementations, compositions can call other functions, so implementations not only need to produce their own errors, but also to detect and react accordingly when one of its child function calls fails. This is possible with a set of built-in functions designed to build, detect and inspect errors within compositions:

  • Throw Error (Z851) — the equivalent to Wikifunctions.Error(), allows you to throw a specific Error Type with a set of error arguments, and as a consequence end the execution.
  • Try-Catch (Z850) — allows you to run a function call watching for a specific Error Type, and if that error is caught, react by running another function call to handle that error case.

You can read more about these built-ins and explore some detailed examples in our documentation about Throwing errors from compositions and Handling errors in compositions, or dig into some great community examples like the compositions for iffy, or name for table header.

How to test failure cases — and why?

As most probably written on some mug, somewhere: failure is not an exception, but an integral part of life. In our Wikifunctions context, if we want to have full control of error states, the most important thing is to document them, and one of the most effective ways to document our functions is by building a good test case coverage.

For example, when using a function such as first matching representation string from lexeme inside of a composition, we should clearly understand what errors it might throw so that we can handle them if needed. We could figure this out by looking at its implementations, but that becomes quite hectic and inaccessible as compositions grow. Tests are a great place to document failure cases — functions like this can now have test cases to prove its two possible error states.

Writing test cases for failure states is a bit more complex, because the top-level call should return a value that can be passed to the validator call. To craft such test cases, you can use another set of built-in functions. In your Test call, use:

And in your validator call, use:

Here's an example: Z30462 successfully tests that, when calling the function first matching representation string from lexeme with a lexeme that doesn't have any forms, it throws an error of type The lexeme doesn't have forms.

For more details and examples, visit the new documentation about Testing your failure use cases.

This should allow us to write more informative error messages, that can even guide contributors to add the right lexeme, or add the right function to the right place, and thus to build the system faster. We are looking forward to see how the improved error system will be used in practise!

No NLG SIG meeting in December

The NLG SIG meeting for December is cancelled due to being too close to the holidays. We wish you all the best time, and see you in 2026!

Fresh Functions weekly: 65 new Functions

This week we had 65 new functions. Here is an incomplete list of functions with implementations and passing tests to get a taste of what functions have been created. Thanks everybody for contributing!

A complete list of all functions sorted by when they were created is available.