Skip to content

Error handling

When using a Zaber device and this library, a number of different exceptional situations may occur. These range from an invalid method argument to various device warnings or failures. An example of a situation is if a device loses power or becomes unresponsive for a timeout period, or if an axis stalls while moving.

This library provides a system to handle these situations.

In the following example, the device is powered off during the execution of the program, an exception is thrown by the library to indicate this situation, and the program catches it.

// const { ascii: { Connection }, Length, MotionLibException } = require('@zaber/motion');

try {
  await axis.moveAbsolute(1, Length.cm);
} catch (err) {
  if ((err instanceof MotionLibException) === false) {
    // if error does not come from the library propagate it.
    throw err;
  }
  console.log(err);
}
/* Outputs:
{ RequestTimeoutException: Device has not responded in given timeout
  at RequestTimeoutException.MotionLibException [as constructor] (zaber-motion-lib/js/src/exceptions/motion_lib_exception.ts:11:5)
    at new RequestTimeoutException (zaber-motion-lib/js/src/exceptions/request_timeout_exception.ts:11:5)
    at Object.convertToException (zaber-motion-lib/js/src/gateway/convert_exceptions.ts:36:10)
    at processResponse (zaber/src/zaber-motion-lib/js/src/gateway/call.ts:70:11)
    at Object.<anonymous> (zaber-motion-lib/js/src/gateway/call.ts:35:10)
    at step (zaber-motion-lib/js/src/gateway/call.ts:32:23)
    at Object.next (zaber-motion-lib/js/src/gateway/call.ts:13:53)
    at fulfilled (zaber-motion-lib/js/src/gateway/call.ts:4:58)
  message: 'Device has not responded in given timeout' }
*/
# from zaber_motion.ascii import Connection
# from zaber_motion import Units, MotionLibException

try:
    axis.move_absolute(1, Units.LENGTH_CENTIMETRES)
except MotionLibException as err:
    print(err)

# Outputs:
# RequestTimeoutException: Device has not responded in given timeout
try
{
    axis.MoveAbsolute(1, Units.Length_Centimetres);
}
catch (MotionLibException e)
{
    Console.WriteLine(e);
}

/* Outputs:
Zaber.Motion.RequestTimeoutException: Device has not responded in given timeout
   at Zaber.Motion.TaskExtension.WaitAndUnwindException(Task task) in zaber-motion-lib/csharp/Zaber.Motion/Utils/TaskExtension.cs:line 16
   at Zaber.Motion.Axis.MoveAbsolute(Double position, Units unit, Boolean waitUntilIdle) in zaber-motion-lib/csharp/Zaber.Motion/Sdk/Axis.cs:line 200
   at Examples.BasicMoves.Program.Run() in zaber-motion-lib/csharp/Examples/BasicMoves/Program.cs:line 30
*/
// import zaber.motion.ascii.Axis;
// import zaber.motion.ascii.Connection;
// import zaber.motion.ascii.Device;
// import zaber.motion.Units;
// import zaber.motion.MotionLibException;

try {
    axis.moveAbsolute(1, Units.LENGTH_CENTIMETRES);
} catch (MotionLibException e) {
    e.printStackTrace();
}
/* Outputs:
zaber.motion.exceptions.RequestTimeoutException: Device has not responded in given timeout
  at zaber.motion.exceptions.ExceptionConverter.convert(ExceptionConverter.java:16)
    at zaber.motion.gateway.Call.parseResponse(Call.java:113)
    at zaber.motion.gateway.Call.lambda$0(Call.java:99)
    at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:642)
    at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
    at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2073)
    at zaber.motion.gateway.Call$2.invoke(Call.java:82)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
*/
try
    axis.moveAbsolute(1, Units.LENGTH_CENTIMETRES);
catch ME
    disp(getReport(ME));
end
% Outputs:
% Java exception occurred:
% zaber.motion.exceptions.RequestTimeoutException: Device has not responded in given timeout
%   at zaber.motion.exceptions.ExceptionConverter.convert(ExceptionConverter.java:16)
%   at zaber.motion.gateway.Call.parseResponse(Call.java:113)
%   at zaber.motion.gateway.Call.lambda$callAsync$0(Call.java:100)
%   at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:602)
%   at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:577)
%   at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474)
%   at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:1962)
%   at zaber.motion.gateway.Call$2.invoke(Call.java:83)
%   at sun.reflect.GeneratedMethodAccessor53.invoke(Unknown Source)
%   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
%   at java.lang.reflect.Method.invoke(Method.java:498)
%   at com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback(CallbackReference.java:470)
%   at com.sun.jna.CallbackReference$DefaultCallbackProxy.callback(CallbackReference.java:500)
try {
    axis.moveAbsolute(1, Units::LENGTH_CENTIMETRES);
} catch (const MotionLibException& e) {
    std::cerr << e.getMessage() << std::endl;
}
/* Outputs:
Device has not responded in given timeout
*/

You may utilize the subclasses of MotionLibException (e.g. RequestTimeoutException) to further distinguish between various errors. Before doing this, ensure that you import the exception subclass at the top of your script:

from zaber_motion import RequestTimeoutException

You may utilize the subclasses of MotionLibException (e.g. RequestTimeoutException) to further distinguish between various errors.

You may utilize the subclasses of MotionLibException (e.g. RequestTimeoutException) to further distinguish between various errors.

You may utilize the subclasses of MotionLibException (e.g. RequestTimeoutException) to further distinguish between various errors.

You may utilize the class of ME.ExceptionObject to further distinguish between various errors. The example below shows how to specifically catch RequestTimeoutException.

catch ME
    switch class(ME.ExceptionObject)
        case 'zaber.motion.exceptions.RequestTimeoutException'
            % Handle the exception here.
        otherwise
            rethrow(ME)
    end
end

You may utilize the subclasses of MotionLibException (e.g. RequestTimeoutException) to further distinguish between various errors.

Additionally, some exceptions have property @prop Details that provides details on the cause of the exception and data from device's reply.

// const { ascii: { Connection }, Length, MovementFailedException } = require('@zaber/motion');

try {
  await axis.moveAbsolute(1, Length.cm);
} catch (err) {
  if (err instanceof MovementFailedException) {
    console.log(err.details.reason);
  }
  throw err;
}
# from zaber_motion.ascii import Connection
# from zaber_motion import Units, MovementFailedException

try:
    axis.move_absolute(1, Units.LENGTH_CENTIMETRES)
except MovementFailedException as err:
    print(err.details.reason)
try
{
    axis.MoveAbsolute(1, Units.Length_Centimetres);
}
catch (MovementFailedException e)
{
    Console.WriteLine(e.Details.Reason);
}
// import zaber.motion.ascii.Axis;
// import zaber.motion.ascii.Connection;
// import zaber.motion.ascii.Device;
// import zaber.motion.Units;
// import zaber.motion.MovementFailedException;

try {
    axis.moveAbsolute(1, Units.LENGTH_CENTIMETRES);
} catch (MovementFailedException e) {
    System.out.println(e.getDetails().getReason());
}
% Example not available for the language
try {
    axis.moveAbsolute(1, Units::LENGTH_CENTIMETRES);
} catch (const MovementFailedException& e) {
    std::cerr << e.getDetails().getReason() << std::endl;
}

Consult the API Reference for a full list of exceptions and their details.