4D Blog

Home Product A New Way to Handle Errors

A New Way to Handle Errors

January 18, 2024

Product

We’ve recently introduced a new error-handling mechanism using the new throw() command.
This marked the first step towards a new error handling system, positioned as close as possible to the code generating them.
In the next phase with 4D v20 R4, we’re expanding this approach to intercept errors during expression execution.
Let’s delve into the details.

try(), a new helpful keyword

With the introduction of 4D v20 R4, developers can now access a useful new keyword: Try(Expression). The Try() keyword enables developers to execute an expression enclosed in parentheses and seamlessly intercept any errors thrown during its execution. These errors can be handled using the Last errors command immediately after the expression execution. This allows you to define your error management as close as possible to the code that generated them and eventually use local variables.

Sample Scenarios before detailed explanations

Division by zero

Consider a simple scenario: division by zero. The following sample demonstrates an Euclidean division method that throws an error and arbitrarily returns zero if the divisor is zero. With Try(), developers can manage errors more elegantly:

#DECLARE($dividend : Real; $divisor : Real)->$result : Real
If ($divisor=0)
  $result:=0
   throw(-12345; "Division by zero!")
Else
  $result:=($dividend/$divisor)
End if

$result:=Try(division($dividend; $divisor))
If (Last errors#Null)
  // Error management
  logErrors(Last errors)
End if

ACCESSING a Document

Managing errors when accessing a document becomes more straightforward if the document doesn’t exist.
To prevent the 4D error dialog from being displayed, an error handler needed to be installed, and the error management code had to be written within this error handler:

$previousErrorHandler:=Method called on error
ON ERR CALL("errorOpenDoc")
var $fileHandle : 4D.FileHandle:=File($path).open()
If ($fileHandle#Null)
  ON ERR CALL("errorReadDoc")
  $text:=$fileHandle.readText()
  If (Last errors#Null)
    $text:="Error reading the file"
  End if
End if
ON ERR CALL($previousErrorHandler)

With the Try() keyword, everything can be written in the same section of code, accessing local variables and then simplifying readability:

var $fileHandle : 4D.FileHandle:=Try(File($path).open())
If ($fileHandle#Null)
  $text:=Try($fileHandle.readText()) || "Error reading the file"
End if

ORDA save function

Another robust use case involves the ORDA save() function, which can generate predictable and unpredictable errors.
Predictable errors, like entity lock, can be directly handled through the result success attribute. However, unpredictable errors, such as primary key duplicates, required an error handler installed with the ON ERR CALL command; otherwise, the 4D error dialog would be displayed:

var $customer : cs.CustomerEntity
// Do something with the $customer entity
$previousErrorHandler:=Method called on error
ON ERR CALL("errorSaveManagement")
$result:=$customer.save()
ON ERR CALL($previousErrorHandler)
If (Not($result.success))
  Case of
    : ($result.status=3)
      // Locked entity management
    : ($result.status=4)
      // Other error management
  End case
End if

But now, the Try() keyword becomes a valuable ally in handling both predictable and unpredictable errors without showing the 4D error dialog:

var $customer : cs.CustomerEntity
// Do something with the $customer entity
$result:=Try($customer.save())
If (Not($result.success))
  Case of
    : ($result.status=3)
      // Locked entity management
    : ($result.status=4)
      // Other error management
  End case
End if

Expression Execution

The Try() keyword accepts any 4D expression between the parentheses, be it variables, assignments, methods, functions, or more. In case of an error, the execution flow stops and returns to the latest Try() keyword encountered (the first found back in the call stack). As a result, you just have to check the error stack after the expression execution to know if errors occurred.
Note that if an error is generated using the throw() command in deferred mode, the execution flow continues until the end of the current method/function execution, providing a simple way to manage error propagation.

Results

On successful execution, Try() returns the result of the expression.
In case of an error, it returns the latest result of the expression or ‘undefined’ if unavailable.
If the expression defines no result (e.g., a method or command with no result), the try() keyword returns ‘undefined.’

About the Error Stack

The current error stack is cleared before the expression is executed, offering a clean slate for error handling within the Try() context. Errors encountered during expression execution are added to the error stack, providing developers with comprehensive information for debugging.

Error Handling

If no current error handler is defined using the ON ERR CALL command, the error dialog won’t disrupt the user experience using Try().
Global and local error handlers set before entering the Try() block won’t be called, ensuring a clean separation between the try context and the rest of the code.
If the expression defines a global or local error handler for the current database, it will be invoked when an error occurs during execution.

Explore New Horizons in Error Management

This new feature opens up a world of possibilities for error management. But it’s only the second step in the new 4D error management era that opens the way to multi-line try-catch blocks!
Share your thoughts and experiences on our forum, and let us know what you think about this new feature.

Happy coding!

Discuss

Tags 21, Handle error, Throw error, v20 R4

Latest related posts

  • June 16, 2025

    Generate, share and use web sessions One-Time Passcodes (OTP)

  • May 20, 2025

    Automatic Refresh of OEM Build Licenses

  • May 16, 2025

    New class to handle incoming TCP connections

Avatar
Damien Fuzeau
• Product Owner •Damien Fuzeau has joined the 4D Product team in February 2019. As a Product Owner, he is in charge of writing user stories, then translating them to functional specifications. His job also entails making sure that the feature implementations delivered are meeting the customer needs.Damien is graduated from the University of Nantes in software engineering. He spent more than 23 years in its former company, first as developer (discovering 4D in 1997), and later as engineering manager and software architect. This company is a 4D OEM partner and deployed 4D based business softwares for thousands users, on hundreds servers. So, Damien is used to 4D development and deployment in a multi-language context.
  • Deutsch
  • Français
  • English
  • Português
  • Čeština
  • Español
  • Italiano
  • 日本語

Categories

Browse categories

  • 4D View Pro
  • 4D Write Pro
  • 4D for Mobile
  • Email
  • Development Mode
  • 4D Language
  • ORDA
  • User Interface / GUI
  • Qodly Studio
  • Server
  • Maintenance
  • Deployment
  • 4D Tutorials
  • Generic
  • 4D Summit sessions and other online videos

Tags

4D-Analyzer 4D for Android 4D for iOS 4D NetKit 4D Qodly Pro 4D View Pro 4D Write Pro 20 R8 20 R9 Administration Authentication Build application CI/CD Class Client/Server Code editor Collections Compatibility settings Formula Listbox Logs Mail Microsoft 365 Network Objects ORDA PDF Pictures Preemptive Programming Qodly Studio REST Scalability Security Session Source control Speed Spreadsheet Tutorial UI User Experience v20 vscode Web Word processor

Tags

4D-Analyzer 4D for Android 4D for iOS 4D NetKit 4D Qodly Pro 4D View Pro 4D Write Pro 20 R8 20 R9 Administration Authentication Build application CI/CD Class Client/Server Code editor Collections Compatibility settings Formula Listbox Logs Mail Microsoft 365 Network Objects ORDA PDF Pictures Preemptive Programming Qodly Studio REST Scalability Security Session Source control Speed Spreadsheet Tutorial UI User Experience v20 vscode Web Word processor
Subscribe to 4D Newsletter

© 2025 4D SAS - All rights reserved
Terms & Conditions | Legal Notices | Data Policy | Cookie Policy | Contact us | Write for us


Subscribe to 4D Newsletter

* Your privacy is very important to us. Please click here to view our Policy

Contact us

Got a question, suggestion or just want to get in touch with the 4D bloggers? Drop us a line!

* Your privacy is very important to us. Please click here to view our Policy