Skip to content

How-to guide

Handle errors

When the client returns a result with a status and when it throws an OpcException, how to evaluate both, and which status codes are common.

This content was machine translated and may contain errors. Read in German

How-to guide

Handle errors ​

The client distinguishes two kinds of errors:

  • Errors of single operations are reported through a status in the result. A value read, the result of a write, or the result of a browse path each carries its own status. If one of many operations fails, the others still receive their result.
  • Errors of the entire call are reported through an OpcException. This happens if there is no connection, the server rejects the request as a whole, or a method call fails.

Evaluate the status ​

Types usedOpcValueOpcStatusOpcStatusCode

An OpcStatus divides results into three groups: IsGood, IsUncertain, and IsBad. Values with an uncertain status carry a value whose quality the server does not guarantee, for example the last usable value of a failed source. Code returns the exact OpcStatusCode, Description a readable description:

csharp
OpcValue value = client.ReadNode("ns=2;s=Machine/Speed");
 
if (value.Status.IsGood)
    Console.WriteLine("Speed: {0}", value.Value);
else if (value.Status.IsUncertain)
    Console.WriteLine("Speed (uncertain): {0}", value.Value);
else
    Console.WriteLine("Read failed: {0} ({1})", value.Status.Code, value.Status.Description);
vbnet
Dim value As OpcValue = client.ReadNode("ns=2;s=Machine/Speed")

If value.Status.IsGood Then
    Console.WriteLine("Speed: {0}", value.Value)
ElseIf value.Status.IsUncertain Then
    Console.WriteLine("Speed (uncertain): {0}", value.Value)
Else
    Console.WriteLine("Read failed: {0} ({1})", value.Status.Code, value.Status.Description)
End If

Writes return an OpcStatus or an OpcStatusCollection directly. Use Code to handle specific causes of errors:

csharp
OpcStatus result = client.WriteNode("ns=2;s=Machine/Setpoint", value: 42.0);
 
if (result.Code == OpcStatusCode.BadUserAccessDenied)
    Console.WriteLine("The user is not allowed to write the setpoint.");
else if (result.IsBad)
    Console.WriteLine("Write failed: {0}", result.Description);
vbnet
Dim result As OpcStatus = client.WriteNode("ns=2;s=Machine/Setpoint", value:=42.0)

If result.Code = OpcStatusCode.BadUserAccessDenied Then
    Console.WriteLine("The user is not allowed to write the setpoint.")
ElseIf result.IsBad Then
    Console.WriteLine("Write failed: {0}", result.Description)
End If

In calls with many commands, each result belongs to the command with the same index, see Write many values in one call.

Handle exceptions ​

Types usedOpcClientOpcDiscoveryClientOpcExceptionOpcStatusCode

An OpcException carries the status code of the error in its Code property. Method calls throw it as soon as the server rejects the call or reports one of the input arguments as invalid:

csharp
try {
    object[] outputs = client.CallMethod(
            "ns=2;s=Machine",
            "ns=2;s=Machine/StartJob",
            "Job 1");
}
catch (OpcException ex) {
    Console.WriteLine("Call failed: {0} ({1})", ex.Code, ex.Message);
}
vbnet
Try
    Dim outputs As Object() = client.CallMethod( _
            "ns=2;s=Machine", _
            "ns=2;s=Machine/StartJob", _
            "Job 1")
Catch ex As OpcException
    Console.WriteLine("Call failed: {0} ({1})", ex.Code, ex.Message)
End Try

Connect also reports errors as an OpcException, for example if the server is not reachable or no endpoint matches the security settings of the client. The client then returns to its previous state:

csharp
try {
    client.Connect();
}
catch (OpcException ex) {
    if (ex.Code == OpcStatusCode.BadSecurityChecksFailed)
        Console.WriteLine("No endpoint matches the security settings of the client.");
    else
        Console.WriteLine("Connect failed: {0}", ex.Code);
}
vbnet
Try
    client.Connect()
Catch ex As OpcException
    If ex.Code = OpcStatusCode.BadSecurityChecksFailed Then
        Console.WriteLine("No endpoint matches the security settings of the client.")
    Else
        Console.WriteLine("Connect failed: {0}", ex.Code)
    End If
End Try

The same applies to OpcDiscoveryClient: if the server is not reachable, closes the channel while connecting, or the scheme of the discovery address is not supported, DiscoverEndpoints, DiscoverServers, and the constructors throw an OpcException stating the reason, for example BadSecureChannelClosed.

Besides OpcException, the usual .NET exceptions occur: ArgumentNullException for missing arguments, InvalidOperationException if a call is not possible in the current state (for example Connect without a server address), and ObjectDisposedException after Dispose. If the application calls a service while there is no connection, the client throws an OpcException with BadServerNotConnected.

Common status codes ​

Status codeMeaningTypical cause
BadNodeIdUnknownThe node does not exist in the address space of the server.wrong identifier or namespace index, see Address nodes by their namespace URI
BadNodeIdInvalidThe syntax of the identifier is invalid.typo in the NodeId string
BadNotReadable, BadNotWritableThe access rights (AccessLevel) of the node do not allow reading or writing.read-only variable
BadUserAccessDeniedThe user of the session has no permission for the operation.user identity with insufficient rights, see Authenticate users
BadTypeMismatchThe value written does not have the data type of the node.for example int written instead of double
BadOutOfRangeThe value is outside the permitted range.limit of the server exceeded
BadWriteNotSupportedThe server does not support the combination of value, status, and timestamps.see Timestamps when writing
BadIndexRangeInvalidThe syntax of the index range is invalid.wrong OpcRange
BadNoMatchA browse path cannot be resolved.wrong path in TranslatePaths
BadTooManyOperationsThe request contains too many operations.your own limit set too high, see How the SDK splits large requests
BadEncodingLimitsExceededThe limits for encoding or decoding were exceeded.very large values, see Data transfer limits
BadTimeoutThe operation exceeded the timeout.OperationTimeout too short or server overloaded
BadServerNotConnectedThe client is not connected to the server.call before Connect or during a connection break
BadSecurityChecksFailedAn error occurred during the security checks.no matching endpoint or rejected certificate
BadIdentityTokenRejectedThe server rejected the user identity.wrong user name or wrong password
BadArgumentsMissing, BadInvalidArgumentInput arguments of a method call are missing or invalid.number or types of the arguments do not match
UncertainLastUsableValueThe source of the value no longer updates it.failed PLC behind the server

Status codes from the server side ​

A server developed with the OPC UA .NET SDK reports some status codes itself or because your code tells it to. The pages on server development describe the following cases:

Status codeWhen the server reports itMore information
BadUserAccessDeniedA user logs on through an endpoint that is not granted for their access control entry. Also for too many simultaneous logon attempts, and for calls to certificate management through GDS whose conditions are not met.Restrict users to endpoints, Limit logon attempts, Manage certificates with GDS
BadNotSupportedAn event handler of the request processing denies a request by setting the Cancel property of the event arguments to true.Validate requests
BadCommunicationErrorYour code reports it on a node if the PLC behind the server is not reachable. The node keeps its last value.Update values
BadAggregateNotSupportedA client requests an aggregate that the server does not support.Aggregated values and values at specific times
BadNoDataA client reads a value at a time before which no raw value exists.Aggregated values and values at specific times
UncertainDataSubNormalWhile calculating an aggregate, the server skipped raw values with a bad status.Aggregated values and values at specific times
BadEncodingLimitsExceededA value exceeds the limits that the server sets for data exchange.Data transfer limits