Repository: gopcua/opcua
Pull request #150 (2019-03-20 15:18:51)

StatusCode implements Error
This patch generates the status code values to implement the error interface.


Patch:
diff --git a/cmd/id/main.go b/cmd/id/main.go
index 65246cb..31823a4 100644
--- a/cmd/id/main.go
+++ b/cmd/id/main.go
@@ -58,7 +58,7 @@ func main() {
 	if err := ioutil.WriteFile(*out, bfmt, 0644); err != nil {
 		log.Fatalf("Error writing %s: %v", *out, err)
 	}
-	log.Printf("Wrote node ids to %s", *out)
+	log.Printf("Wrote %s", *out)
 }
 
 var tmpl = template.Must(template.New("").Parse(`
diff --git a/cmd/service/goname/format.go b/cmd/service/goname/format.go
new file mode 100644
index 0000000..6dfcc32
--- /dev/null
+++ b/cmd/service/goname/format.go
@@ -0,0 +1,24 @@
+package goname
+
+import "strings"
+
+var (
+	idents = strings.NewReplacer(
+		"Guid", "GUID",
+		"Id", "ID",
+		"Json", "JSON",
+		"QualityOfService", "QoS",
+		"Uadp", "UADP",
+		"Uri", "URI",
+		"Url", "URL",
+		"Xml", "XML",
+	)
+
+	fixes = strings.NewReplacer(
+		"IDentity", "Identity",
+	)
+)
+
+func Format(s string) string {
+	return fixes.Replace(idents.Replace(s))
+}
diff --git a/cmd/service/main.go b/cmd/service/main.go
index 15b9a80..6090019 100644
--- a/cmd/service/main.go
+++ b/cmd/service/main.go
@@ -11,6 +11,8 @@ import (
 	"path"
 	"strings"
 	"text/template"
+
+	"github.com/gopcua/opcua/cmd/service/goname"
 )
 
 var in, out, pkg string
@@ -94,7 +96,7 @@ func Enums(dict *TypeDictionary) []Type {
 	var enums []Type
 	for _, t := range dict.Enums {
 		e := Type{
-			Name: goName(t.Name),
+			Name: goname.Format(t.Name),
 			Kind: KindEnum,
 		}
 
@@ -111,7 +113,7 @@ func Enums(dict *TypeDictionary) []Type {
 
 		for _, val := range t.Values {
 			v := Value{
-				Name:  goName(e.Name + val.Name),
+				Name:  goname.Format(e.Name + val.Name),
 				Value: val.Value,
 			}
 			e.Values = append(e.Values, v)
@@ -141,7 +143,7 @@ func ExtObjects(dict *TypeDictionary) []Type {
 		}
 
 		o := Type{
-			Name: goName(t.Name),
+			Name: goname.Format(t.Name),
 			Kind: KindExtensionObject,
 			Base: baseType,
 		}
@@ -154,7 +156,7 @@ func ExtObjects(dict *TypeDictionary) []Type {
 			}
 
 			of := Field{
-				Name: goName(f.Name),
+				Name: goname.Format(f.Name),
 				Type: goFieldType(f),
 			}
 			o.Fields = append(o.Fields, of)
@@ -288,7 +290,7 @@ func goFieldType(f *StructField) string {
 	t, builtin := builtins[f.Type]
 	if t == "" {
 		prefix := strings.NewReplacer("ua:", "", "tns:", "")
-		t = goName(prefix.Replace(f.Type))
+		t = goname.Format(prefix.Replace(f.Type))
 	}
 	if !f.IsEnum && !builtin {
 		t = "*" + t
@@ -298,20 +300,3 @@ func goFieldType(f *StructField) string {
 	}
 	return t
 }
-
-func goName(s string) string {
-	r1 := strings.NewReplacer(
-		"Guid", "GUID",
-		"Id", "ID",
-		"Json", "JSON",
-		"QualityOfService", "QoS",
-		"Uadp", "UADP",
-		"Uri", "URI",
-		"Url", "URL",
-		"Xml", "XML",
-	)
-	r2 := strings.NewReplacer(
-		"IDentity", "Identity",
-	)
-	return r2.Replace(r1.Replace(s))
-}
diff --git a/cmd/status/main.go b/cmd/status/main.go
index e636613..69d7daa 100644
--- a/cmd/status/main.go
+++ b/cmd/status/main.go
@@ -14,13 +14,15 @@ import (
 	"os"
 	"strings"
 	"text/template"
+
+	"github.com/gopcua/opcua/cmd/service/goname"
 )
 
 func main() {
 	log.SetFlags(0)
 
 	in := flag.String("in", "schema/StatusCode.csv", "path to StatusCodes.csv")
-	out := flag.String("out", "status/status_gen.go", "path to generated file")
+	out := flag.String("out", "ua/status_gen.go", "path to generated file")
 	flag.Parse()
 
 	if *in == "" {
@@ -49,6 +51,11 @@ func main() {
 		log.Fatalf("Error parsing csv: %v", err)
 	}
 
+	// goify the name and prefix with Status
+	for i := range rows {
+		rows[i][0] = "Status" + goname.Format(rows[i][0])
+	}
+
 	var b bytes.Buffer
 	if err := tmpl.Execute(&b, rows); err != nil {
 		log.Fatalf("Error generating code: %v", err)
@@ -62,7 +69,7 @@ func main() {
 	if err := ioutil.WriteFile(*out, bfmt, 0644); err != nil {
 		log.Fatalf("Error writing %s: %v", *out, err)
 	}
-	log.Printf("Wrote status codes to %s", *out)
+	log.Printf("Wrote %s", *out)
 }
 
 var tmpl = template.Must(template.New("").Parse(`
@@ -72,10 +79,35 @@ var tmpl = template.Must(template.New("").Parse(`
 
 // Code generated by cmd/status. DO NOT EDIT!
 
-package status
+package ua
+
+import "fmt"
 
-const (
-	{{range .}}{{index . 0}} = {{index . 1}}
+// StatusCode is an error type for a status code.
+type StatusCode uint32
+
+func (n StatusCode) Error() string {
+	if d, ok := StatusCodes[n]; ok {
+		return fmt.Sprintf("%s (%s/0x%8X)", d.Text, d.Name, n)
+	}
+	return fmt.Sprintf("0x%08X", n)
+}
+
+var (
+	StatusOK StatusCode = 0x0
+	{{range .}}{{index . 0}} StatusCode = {{index . 1}}
 	{{end}}
 )
+
+type StatusCodeDesc struct {
+	Name string
+	Text string
+}
+
+// StatusCodes maps status codes to the status code error types.
+var StatusCodes = map[StatusCode]StatusCodeDesc{
+	StatusOK: StatusCodeDesc{Name: "OK", Text: "OK"},
+	{{range .}}{{index . 0}}: StatusCodeDesc{ Name: "{{index . 0}}", Text: "{{index . 2}}" },
+	{{end}}
+}
 `))
diff --git a/errors/doc.go b/errors/doc.go
deleted file mode 100644
index d64cb25..0000000
--- a/errors/doc.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2018-2019 opcua authors. All rights reserved.
-// Use of this source code is governed by a MIT-style license that can be
-// found in the LICENSE file.
-
-/*
-Package errors defines the errors used in multiple packages in common.
-*/
-package errors
diff --git a/errors/errors.go b/errors/errors.go
deleted file mode 100644
index 5f4dda7..0000000
--- a/errors/errors.go
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2018-2019 opcua authors. All rights reserved.
-// Use of this source code is governed by a MIT-style license that can be
-// found in the LICENSE file.
-
-package errors
-
-import (
-	"fmt"
-
-	"github.com/pkg/errors"
-)
-
-// Cause Cause returns the underlying cause of the error, if possible.
-// An error value has a cause if it implements the following interface:
-//
-// This function just wraps the Cause in pkg/errors library.
-func Cause(err error) error {
-	return errors.Cause(err)
-}
-
-// Errorf formats according to a format specifier and returns the string as a value
-// that satisfies error. Errorf also records the stack trace at the point it was called.
-//
-// This function just wraps the Errorf in pkg/errors library.
-func Errorf(format string, args ...interface{}) error {
-	return errors.Errorf(format, args...)
-}
-
-// New returns an error that formats as the given text.
-//
-// This function just wraps the New in pkg/errors library.
-func New(text string) error {
-	return errors.New(text)
-}
-
-// WithMessage annotates err with a new message. If err is nil, WithMessage returns nil.
-//
-// This function just wraps the WithMessage in pkg/errors library.
-func WithMessage(err error, message string) error {
-	return errors.WithMessage(err, message)
-}
-
-// WithStack annotates err with a stack trace at the point WithStack was called.
-// If err is nil, WithStack returns nil.
-//
-// This function just wraps the WithStack in pkg/errors library.
-func WithStack(err error) error {
-	return errors.WithStack(err)
-}
-
-// Wrap returns an error annotating err with a stack trace at the point Wrap is called,
-// and the supplied message. If err is nil, Wrap returns nil.
-//
-// This function just wraps the Wrap in pkg/errors library.
-func Wrap(err error, message string) error {
-	return errors.Wrap(err, message)
-}
-
-// Wrapf returns an error annotating err with a stack trace at the point Wrapf is called,
-// and the format specifier. If err is nil, Wrapf returns nil.
-//
-// This function just wraps the Wrapf in pkg/errors library.
-func Wrapf(err error, format string, args ...interface{}) error {
-	return errors.Wrapf(err, format, args...)
-}
-
-// Frame represents a program counter inside a stack frame.
-//
-// This type is just an alias of Frame in pkg/errors library.
-type Frame = errors.Frame
-
-// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
-//
-// This type is just an alias of Frame in pkg/errors library.
-type StackTrace = errors.StackTrace
-
-// ErrTooShortToDecode indicates the length of user input is too short to be decoded.
-type ErrTooShortToDecode struct {
-	Type    interface{}
-	Message string
-}
-
-// NewErrTooShortToDecode creates a ErrTooShortToDecode.
-func NewErrTooShortToDecode(decodedType interface{}, msg string) *ErrTooShortToDecode {
-	return &ErrTooShortToDecode{
-		Type:    decodedType,
-		Message: msg,
-	}
-}
-
-// Error returns the type of receiver of decoder method and some additional message.
-func (e *ErrTooShortToDecode) Error() string {
-	return fmt.Sprintf("too short to decode as %T: %s", e.Type, e.Message)
-}
-
-// ErrInvalidLength indicates the value in Length field is invalid.
-type ErrInvalidLength struct {
-	Type    interface{}
-	Message string
-}
-
-// NewErrInvalidLength creates a ErrInvalidLength.
-func NewErrInvalidLength(rcvType interface{}, msg string) *ErrInvalidLength {
-	return &ErrInvalidLength{
-		Type:    rcvType,
-		Message: msg,
-	}
-}
-
-// Error returns the type of receiver and some additional message.
-func (e *ErrInvalidLength) Error() string {
-	return fmt.Sprintf("got invalid Length in %T: %s", e.Type, e.Message)
-}
-
-// ErrUnsupported indicates the value in Version field is invalid.
-type ErrUnsupported struct {
-	Type    interface{}
-	Message string
-}
-
-// NewErrUnsupported creates a ErrUnsupported.
-func NewErrUnsupported(unsupportedType interface{}, msg string) *ErrUnsupported {
-	return &ErrUnsupported{
-		Type:    unsupportedType,
-		Message: msg,
-	}
-}
-
-// Error returns the type of receiver and some additional message.
-func (e *ErrUnsupported) Error() string {
-	return fmt.Sprintf("unsupported %T: %s", e.Type, e.Message)
-}
-
-// ErrInvalidType indicates the value in Type/Code field is invalid.
-type ErrInvalidType struct {
-	Type    interface{}
-	Action  string
-	Message string
-}
-
-// NewErrInvalidType creates a ErrInvalidType.
-//
-// The parameter action is the action taken when this error is raised(e.g., "decode").
-func NewErrInvalidType(invalidType interface{}, action, msg string) *ErrInvalidType {
-	return &ErrInvalidType{
-		Type:    invalidType,
-		Action:  action,
-		Message: msg,
-	}
-}
-
-// Error returns the type of receiver and some additional message.
-func (e *ErrInvalidType) Error() string {
-	return fmt.Sprintf("cannot %s as %T: %s", e.Action, e.Type, e.Message)
-}
-
-// ErrReceiverNil indicates the receiver is nil.
-type ErrReceiverNil struct {
-	Type interface{}
-}
-
-// NewErrReceiverNil creates a ErrReceiverNil.
-func NewErrReceiverNil(rcvType interface{}) *ErrReceiverNil {
-	return &ErrReceiverNil{
-		Type: rcvType,
-	}
-}
-
-// Error returns the type of receiver.
-func (e *ErrReceiverNil) Error() string {
-	return fmt.Sprintf("Receiver %T is nil.", e.Type)
-}
diff --git a/status/status_gen.go b/status/status_gen.go
deleted file mode 100644
index 05ede54..0000000
--- a/status/status_gen.go
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright 2018-2019 opcua authors. All rights reserved.
-// Use of this source code is governed by a MIT-style license that can be
-// found in the LICENSE file.
-
-// Code generated by cmd/status. DO NOT EDIT!
-
-package status
-
-const (
-	BadUnexpectedError                      = 0x80010000
-	BadInternalError                        = 0x80020000
-	BadOutOfMemory                          = 0x80030000
-	BadResourceUnavailable                  = 0x80040000
-	BadCommunicationError                   = 0x80050000
-	BadEncodingError                        = 0x80060000
-	BadDecodingError                        = 0x80070000
-	BadEncodingLimitsExceeded               = 0x80080000
-	BadRequestTooLarge                      = 0x80B80000
-	BadResponseTooLarge                     = 0x80B90000
-	BadUnknownResponse                      = 0x80090000
-	BadTimeout                              = 0x800A0000
-	BadServiceUnsupported                   = 0x800B0000
-	BadShutdown                             = 0x800C0000
-	BadServerNotConnected                   = 0x800D0000
-	BadServerHalted                         = 0x800E0000
-	BadNothingToDo                          = 0x800F0000
-	BadTooManyOperations                    = 0x80100000
-	BadTooManyMonitoredItems                = 0x80DB0000
-	BadDataTypeIdUnknown                    = 0x80110000
-	BadCertificateInvalid                   = 0x80120000
-	BadSecurityChecksFailed                 = 0x80130000
-	BadCertificatePolicyCheckFailed         = 0x81140000
-	BadCertificateTimeInvalid               = 0x80140000
-	BadCertificateIssuerTimeInvalid         = 0x80150000
-	BadCertificateHostNameInvalid           = 0x80160000
-	BadCertificateUriInvalid                = 0x80170000
-	BadCertificateUseNotAllowed             = 0x80180000
-	BadCertificateIssuerUseNotAllowed       = 0x80190000
-	BadCertificateUntrusted                 = 0x801A0000
-	BadCertificateRevocationUnknown         = 0x801B0000
-	BadCertificateIssuerRevocationUnknown   = 0x801C0000
-	BadCertificateRevoked                   = 0x801D0000
-	BadCertificateIssuerRevoked             = 0x801E0000
-	BadCertificateChainIncomplete           = 0x810D0000
-	BadUserAccessDenied                     = 0x801F0000
-	BadIdentityTokenInvalid                 = 0x80200000
-	BadIdentityTokenRejected                = 0x80210000
-	BadSecureChannelIdInvalid               = 0x80220000
-	BadInvalidTimestamp                     = 0x80230000
-	BadNonceInvalid                         = 0x80240000
-	BadSessionIdInvalid                     = 0x80250000
-	BadSessionClosed                        = 0x80260000
-	BadSessionNotActivated                  = 0x80270000
-	BadSubscriptionIdInvalid                = 0x80280000
-	BadRequestHeaderInvalid                 = 0x802A0000
-	BadTimestampsToReturnInvalid            = 0x802B0000
-	BadRequestCancelledByClient             = 0x802C0000
-	BadTooManyArguments                     = 0x80E50000
-	BadLicenseExpired                       = 0x810E0000
-	BadLicenseLimitsExceeded                = 0x810F0000
-	BadLicenseNotAvailable                  = 0x81100000
-	GoodSubscriptionTransferred             = 0x002D0000
-	GoodCompletesAsynchronously             = 0x002E0000
-	GoodOverload                            = 0x002F0000
-	GoodClamped                             = 0x00300000
-	BadNoCommunication                      = 0x80310000
-	BadWaitingForInitialData                = 0x80320000
-	BadNodeIdInvalid                        = 0x80330000
-	BadNodeIdUnknown                        = 0x80340000
-	BadAttributeIdInvalid                   = 0x80350000
-	BadIndexRangeInvalid                    = 0x80360000
-	BadIndexRangeNoData                     = 0x80370000
-	BadDataEncodingInvalid                  = 0x80380000
-	BadDataEncodingUnsupported              = 0x80390000
-	BadNotReadable                          = 0x803A0000
-	BadNotWritable                          = 0x803B0000
-	BadOutOfRange                           = 0x803C0000
-	BadNotSupported                         = 0x803D0000
-	BadNotFound                             = 0x803E0000
-	BadObjectDeleted                        = 0x803F0000
-	BadNotImplemented                       = 0x80400000
-	BadMonitoringModeInvalid                = 0x80410000
-	BadMonitoredItemIdInvalid               = 0x80420000
-	BadMonitoredItemFilterInvalid           = 0x80430000
-	BadMonitoredItemFilterUnsupported       = 0x80440000
-	BadFilterNotAllowed                     = 0x80450000
-	BadStructureMissing                     = 0x80460000
-	BadEventFilterInvalid                   = 0x80470000
-	BadContentFilterInvalid                 = 0x80480000
-	BadFilterOperatorInvalid                = 0x80C10000
-	BadFilterOperatorUnsupported            = 0x80C20000
-	BadFilterOperandCountMismatch           = 0x80C30000
-	BadFilterOperandInvalid                 = 0x80490000
-	BadFilterElementInvalid                 = 0x80C40000
-	BadFilterLiteralInvalid                 = 0x80C50000
-	BadContinuationPointInvalid             = 0x804A0000
-	BadNoContinuationPoints                 = 0x804B0000
-	BadReferenceTypeIdInvalid               = 0x804C0000
-	BadBrowseDirectionInvalid               = 0x804D0000
-	BadNodeNotInView                        = 0x804E0000
-	BadNumericOverflow                      = 0x81120000
-	BadServerUriInvalid                     = 0x804F0000
-	BadServerNameMissing                    = 0x80500000
-	BadDiscoveryUrlMissing                  = 0x80510000
-	BadSempahoreFileMissing                 = 0x80520000
-	BadRequestTypeInvalid                   = 0x80530000
-	BadSecurityModeRejected                 = 0x80540000
-	BadSecurityPolicyRejected               = 0x80550000
-	BadTooManySessions                      = 0x80560000
-	BadUserSignatureInvalid                 = 0x80570000
-	BadApplicationSignatureInvalid          = 0x80580000
-	BadNoValidCertificates                  = 0x80590000
-	BadIdentityChangeNotSupported           = 0x80C60000
-	BadRequestCancelledByRequest            = 0x805A0000
-	BadParentNodeIdInvalid                  = 0x805B0000
-	BadReferenceNotAllowed                  = 0x805C0000
-	BadNodeIdRejected                       = 0x805D0000
-	BadNodeIdExists                         = 0x805E0000
-	BadNodeClassInvalid                     = 0x805F0000
-	BadBrowseNameInvalid                    = 0x80600000
-	BadBrowseNameDuplicated                 = 0x80610000
-	BadNodeAttributesInvalid                = 0x80620000
-	BadTypeDefinitionInvalid                = 0x80630000
-	BadSourceNodeIdInvalid                  = 0x80640000
-	BadTargetNodeIdInvalid                  = 0x80650000
-	BadDuplicateReferenceNotAllowed         = 0x80660000
-	BadInvalidSelfReference                 = 0x80670000
-	BadReferenceLocalOnly                   = 0x80680000
-	BadNoDeleteRights                       = 0x80690000
-	UncertainReferenceNotDeleted            = 0x40BC0000
-	BadServerIndexInvalid                   = 0x806A0000
-	BadViewIdUnknown                        = 0x806B0000
-	BadViewTimestampInvalid                 = 0x80C90000
-	BadViewParameterMismatch                = 0x80CA0000
-	BadViewVersionInvalid                   = 0x80CB0000
-	UncertainNotAllNodesAvailable           = 0x40C00000
-	GoodResultsMayBeIncomplete              = 0x00BA0000
-	BadNotTypeDefinition                    = 0x80C80000
-	UncertainReferenceOutOfServer           = 0x406C0000
-	BadTooManyMatches                       = 0x806D0000
-	BadQueryTooComplex                      = 0x806E0000
-	BadNoMatch                              = 0x806F0000
-	BadMaxAgeInvalid                        = 0x80700000
-	BadSecurityModeInsufficient             = 0x80E60000
-	BadHistoryOperationInvalid              = 0x80710000
-	BadHistoryOperationUnsupported          = 0x80720000
-	BadInvalidTimestampArgument             = 0x80BD0000
-	BadWriteNotSupported                    = 0x80730000
-	BadTypeMismatch                         = 0x80740000
-	BadMethodInvalid                        = 0x80750000
-	BadArgumentsMissing                     = 0x80760000
-	BadNotExecutable                        = 0x81110000
-	BadTooManySubscriptions                 = 0x80770000
-	BadTooManyPublishRequests               = 0x80780000
-	BadNoSubscription                       = 0x80790000
-	BadSequenceNumberUnknown                = 0x807A0000
-	BadMessageNotAvailable                  = 0x807B0000
-	BadInsufficientClientProfile            = 0x807C0000
-	BadStateNotActive                       = 0x80BF0000
-	BadAlreadyExists                        = 0x81150000
-	BadTcpServerTooBusy                     = 0x807D0000
-	BadTcpMessageTypeInvalid                = 0x807E0000
-	BadTcpSecureChannelUnknown              = 0x807F0000
-	BadTcpMessageTooLarge                   = 0x80800000
-	BadTcpNotEnoughResources                = 0x80810000
-	BadTcpInternalError                     = 0x80820000
-	BadTcpEndpointUrlInvalid                = 0x80830000
-	BadRequestInterrupted                   = 0x80840000
-	BadRequestTimeout                       = 0x80850000
-	BadSecureChannelClosed                  = 0x80860000
-	BadSecureChannelTokenUnknown            = 0x80870000
-	BadSequenceNumberInvalid                = 0x80880000
-	BadProtocolVersionUnsupported           = 0x80BE0000
-	BadConfigurationError                   = 0x80890000
-	BadNotConnected                         = 0x808A0000
-	BadDeviceFailure                        = 0x808B0000
-	BadSensorFailure                        = 0x808C0000
-	BadOutOfService                         = 0x808D0000
-	BadDeadbandFilterInvalid                = 0x808E0000
-	UncertainNoCommunicationLastUsableValue = 0x408F0000
-	UncertainLastUsableValue                = 0x40900000
-	UncertainSubstituteValue                = 0x40910000
-	UncertainInitialValue                   = 0x40920000
-	UncertainSensorNotAccurate              = 0x40930000
-	UncertainEngineeringUnitsExceeded       = 0x40940000
-	UncertainSubNormal                      = 0x40950000
-	GoodLocalOverride                       = 0x00960000
-	BadRefreshInProgress                    = 0x80970000
-	BadConditionAlreadyDisabled             = 0x80980000
-	BadConditionAlreadyEnabled              = 0x80CC0000
-	BadConditionDisabled                    = 0x80990000
-	BadEventIdUnknown                       = 0x809A0000
-	BadEventNotAcknowledgeable              = 0x80BB0000
-	BadDialogNotActive                      = 0x80CD0000
-	BadDialogResponseInvalid                = 0x80CE0000
-	BadConditionBranchAlreadyAcked          = 0x80CF0000
-	BadConditionBranchAlreadyConfirmed      = 0x80D00000
-	BadConditionAlreadyShelved              = 0x80D10000
-	BadConditionNotShelved                  = 0x80D20000
-	BadShelvingTimeOutOfRange               = 0x80D30000
-	BadNoData                               = 0x809B0000
-	BadBoundNotFound                        = 0x80D70000
-	BadBoundNotSupported                    = 0x80D80000
-	BadDataLost                             = 0x809D0000
-	BadDataUnavailable                      = 0x809E0000
-	BadEntryExists                          = 0x809F0000
-	BadNoEntryExists                        = 0x80A00000
-	BadTimestampNotSupported                = 0x80A10000
-	GoodEntryInserted                       = 0x00A20000
-	GoodEntryReplaced                       = 0x00A30000
-	UncertainDataSubNormal                  = 0x40A40000
-	GoodNoData                              = 0x00A50000
-	GoodMoreData                            = 0x00A60000
-	BadAggregateListMismatch                = 0x80D40000
-	BadAggregateNotSupported                = 0x80D50000
-	BadAggregateInvalidInputs               = 0x80D60000
-	BadAggregateConfigurationRejected       = 0x80DA0000
-	GoodDataIgnored                         = 0x00D90000
-	BadRequestNotAllowed                    = 0x80E40000
-	BadRequestNotComplete                   = 0x81130000
-	GoodEdited                              = 0x00DC0000
-	GoodPostActionFailed                    = 0x00DD0000
-	UncertainDominantValueChanged           = 0x40DE0000
-	GoodDependentValueChanged               = 0x00E00000
-	BadDominantValueChanged                 = 0x80E10000
-	UncertainDependentValueChanged          = 0x40E20000
-	BadDependentValueChanged                = 0x80E30000
-	GoodCommunicationEvent                  = 0x00A70000
-	GoodShutdownEvent                       = 0x00A80000
-	GoodCallAgain                           = 0x00A90000
-	GoodNonCriticalTimeout                  = 0x00AA0000
-	BadInvalidArgument                      = 0x80AB0000
-	BadConnectionRejected                   = 0x80AC0000
-	BadDisconnect                           = 0x80AD0000
-	BadConnectionClosed                     = 0x80AE0000
-	BadInvalidState                         = 0x80AF0000
-	BadEndOfStream                          = 0x80B00000
-	BadNoDataAvailable                      = 0x80B10000
-	BadWaitingForResponse                   = 0x80B20000
-	BadOperationAbandoned                   = 0x80B30000
-	BadExpectedStreamToBlock                = 0x80B40000
-	BadWouldBlock                           = 0x80B50000
-	BadSyntaxError                          = 0x80B60000
-	BadMaxConnectionsReached                = 0x80B70000
-)
diff --git a/ua/datatypes.go b/ua/datatypes.go
index 46f0b88..ece6027 100644
--- a/ua/datatypes.go
+++ b/ua/datatypes.go
@@ -234,6 +234,4 @@ func (l *LocalizedText) UpdateMask() {
 	}
 }
 
-type StatusCode uint32
-
 type XmlElement string
diff --git a/ua/service.go b/ua/service.go
index b43793a..1d9e53d 100644
--- a/ua/service.go
+++ b/ua/service.go
@@ -7,8 +7,6 @@ package ua
 import (
 	"fmt"
 	"reflect"
-
-	"github.com/gopcua/opcua/errors"
 )
 
 var (
@@ -45,7 +43,7 @@ func DecodeService(b []byte) (*ExpandedNodeID, interface{}, error) {
 	id := uint16(typeID.NodeID.IntID())
 	typ := serviceType[id]
 	if typ == nil {
-		return nil, nil, errors.NewErrUnsupported(id, "unsupported or not implemented yet.")
+		return nil, nil, StatusBadServiceUnsupported
 	}
 
 	v := reflect.New(typ.Elem()).Interface()
diff --git a/ua/status_gen.go b/ua/status_gen.go
new file mode 100644
index 0000000..1b9c8af
--- /dev/null
+++ b/ua/status_gen.go
@@ -0,0 +1,503 @@
+// Copyright 2018-2019 opcua authors. All rights reserved.
+// Use of this source code is governed by a MIT-style license that can be
+// found in the LICENSE file.
+
+// Code generated by cmd/status. DO NOT EDIT!
+
+package ua
+
+import "fmt"
+
+// StatusCode is an error type for a status code.
+type StatusCode uint32
+
+func (n StatusCode) Error() string {
+	if d, ok := StatusCodes[n]; ok {
+		return fmt.Sprintf("%s (%s/0x%8X)", d.Text, d.Name, n)
+	}
+	return fmt.Sprintf("0x%08X", n)
+}
+
+var (
+	StatusOK                                      StatusCode = 0x0
+	StatusBadUnexpectedError                      StatusCode = 0x80010000
+	StatusBadInternalError                        StatusCode = 0x80020000
+	StatusBadOutOfMemory                          StatusCode = 0x80030000
+	StatusBadResourceUnavailable                  StatusCode = 0x80040000
+	StatusBadCommunicationError                   StatusCode = 0x80050000
+	StatusBadEncodingError                        StatusCode = 0x80060000
+	StatusBadDecodingError                        StatusCode = 0x80070000
+	StatusBadEncodingLimitsExceeded               StatusCode = 0x80080000
+	StatusBadRequestTooLarge                      StatusCode = 0x80B80000
+	StatusBadResponseTooLarge                     StatusCode = 0x80B90000
+	StatusBadUnknownResponse                      StatusCode = 0x80090000
+	StatusBadTimeout                              StatusCode = 0x800A0000
+	StatusBadServiceUnsupported                   StatusCode = 0x800B0000
+	StatusBadShutdown                             StatusCode = 0x800C0000
+	StatusBadServerNotConnected                   StatusCode = 0x800D0000
+	StatusBadServerHalted                         StatusCode = 0x800E0000
+	StatusBadNothingToDo                          StatusCode = 0x800F0000
+	StatusBadTooManyOperations                    StatusCode = 0x80100000
+	StatusBadTooManyMonitoredItems                StatusCode = 0x80DB0000
+	StatusBadDataTypeIDUnknown                    StatusCode = 0x80110000
+	StatusBadCertificateInvalid                   StatusCode = 0x80120000
+	StatusBadSecurityChecksFailed                 StatusCode = 0x80130000
+	StatusBadCertificatePolicyCheckFailed         StatusCode = 0x81140000
+	StatusBadCertificateTimeInvalid               StatusCode = 0x80140000
+	StatusBadCertificateIssuerTimeInvalid         StatusCode = 0x80150000
+	StatusBadCertificateHostNameInvalid           StatusCode = 0x80160000
+	StatusBadCertificateURIInvalid                StatusCode = 0x80170000
+	StatusBadCertificateUseNotAllowed             StatusCode = 0x80180000
+	StatusBadCertificateIssuerUseNotAllowed       StatusCode = 0x80190000
+	StatusBadCertificateUntrusted                 StatusCode = 0x801A0000
+	StatusBadCertificateRevocationUnknown         StatusCode = 0x801B0000
+	StatusBadCertificateIssuerRevocationUnknown   StatusCode = 0x801C0000
+	StatusBadCertificateRevoked                   StatusCode = 0x801D0000
+	StatusBadCertificateIssuerRevoked             StatusCode = 0x801E0000
+	StatusBadCertificateChainIncomplete           StatusCode = 0x810D0000
+	StatusBadUserAccessDenied                     StatusCode = 0x801F0000
+	StatusBadIdentityTokenInvalid                 StatusCode = 0x80200000
+	StatusBadIdentityTokenRejected                StatusCode = 0x80210000
+	StatusBadSecureChannelIDInvalid               StatusCode = 0x80220000
+	StatusBadInvalidTimestamp                     StatusCode = 0x80230000
+	StatusBadNonceInvalid                         StatusCode = 0x80240000
+	StatusBadSessionIDInvalid                     StatusCode = 0x80250000
+	StatusBadSessionClosed                        StatusCode = 0x80260000
+	StatusBadSessionNotActivated                  StatusCode = 0x80270000
+	StatusBadSubscriptionIDInvalid                StatusCode = 0x80280000
+	StatusBadRequestHeaderInvalid                 StatusCode = 0x802A0000
+	StatusBadTimestampsToReturnInvalid            StatusCode = 0x802B0000
+	StatusBadRequestCancelledByClient             StatusCode = 0x802C0000
+	StatusBadTooManyArguments                     StatusCode = 0x80E50000
+	StatusBadLicenseExpired                       StatusCode = 0x810E0000
+	StatusBadLicenseLimitsExceeded                StatusCode = 0x810F0000
+	StatusBadLicenseNotAvailable                  StatusCode = 0x81100000
+	StatusGoodSubscriptionTransferred             StatusCode = 0x002D0000
+	StatusGoodCompletesAsynchronously             StatusCode = 0x002E0000
+	StatusGoodOverload                            StatusCode = 0x002F0000
+	StatusGoodClamped                             StatusCode = 0x00300000
+	StatusBadNoCommunication                      StatusCode = 0x80310000
+	StatusBadWaitingForInitialData                StatusCode = 0x80320000
+	StatusBadNodeIDInvalid                        StatusCode = 0x80330000
+	StatusBadNodeIDUnknown                        StatusCode = 0x80340000
+	StatusBadAttributeIDInvalid                   StatusCode = 0x80350000
+	StatusBadIndexRangeInvalid                    StatusCode = 0x80360000
+	StatusBadIndexRangeNoData                     StatusCode = 0x80370000
+	StatusBadDataEncodingInvalid                  StatusCode = 0x80380000
+	StatusBadDataEncodingUnsupported              StatusCode = 0x80390000
+	StatusBadNotReadable                          StatusCode = 0x803A0000
+	StatusBadNotWritable                          StatusCode = 0x803B0000
+	StatusBadOutOfRange                           StatusCode = 0x803C0000
+	StatusBadNotSupported                         StatusCode = 0x803D0000
+	StatusBadNotFound                             StatusCode = 0x803E0000
+	StatusBadObjectDeleted                        StatusCode = 0x803F0000
+	StatusBadNotImplemented                       StatusCode = 0x80400000
+	StatusBadMonitoringModeInvalid                StatusCode = 0x80410000
+	StatusBadMonitoredItemIDInvalid               StatusCode = 0x80420000
+	StatusBadMonitoredItemFilterInvalid           StatusCode = 0x80430000
+	StatusBadMonitoredItemFilterUnsupported       StatusCode = 0x80440000
+	StatusBadFilterNotAllowed                     StatusCode = 0x80450000
+	StatusBadStructureMissing                     StatusCode = 0x80460000
+	StatusBadEventFilterInvalid                   StatusCode = 0x80470000
+	StatusBadContentFilterInvalid                 StatusCode = 0x80480000
+	StatusBadFilterOperatorInvalid                StatusCode = 0x80C10000
+	StatusBadFilterOperatorUnsupported            StatusCode = 0x80C20000
+	StatusBadFilterOperandCountMismatch           StatusCode = 0x80C30000
+	StatusBadFilterOperandInvalid                 StatusCode = 0x80490000
+	StatusBadFilterElementInvalid                 StatusCode = 0x80C40000
+	StatusBadFilterLiteralInvalid                 StatusCode = 0x80C50000
+	StatusBadContinuationPointInvalid             StatusCode = 0x804A0000
+	StatusBadNoContinuationPoints                 StatusCode = 0x804B0000
+	StatusBadReferenceTypeIDInvalid               StatusCode = 0x804C0000
+	StatusBadBrowseDirectionInvalid               StatusCode = 0x804D0000
+	StatusBadNodeNotInView                        StatusCode = 0x804E0000
+	StatusBadNumericOverflow                      StatusCode = 0x81120000
+	StatusBadServerURIInvalid                     StatusCode = 0x804F0000
+	StatusBadServerNameMissing                    StatusCode = 0x80500000
+	StatusBadDiscoveryURLMissing                  StatusCode = 0x80510000
+	StatusBadSempahoreFileMissing                 StatusCode = 0x80520000
+	StatusBadRequestTypeInvalid                   StatusCode = 0x80530000
+	StatusBadSecurityModeRejected                 StatusCode = 0x80540000
+	StatusBadSecurityPolicyRejected               StatusCode = 0x80550000
+	StatusBadTooManySessions                      StatusCode = 0x80560000
+	StatusBadUserSignatureInvalid                 StatusCode = 0x80570000
+	StatusBadApplicationSignatureInvalid          StatusCode = 0x80580000
+	StatusBadNoValidCertificates                  StatusCode = 0x80590000
+	StatusBadIdentityChangeNotSupported           StatusCode = 0x80C60000
+	StatusBadRequestCancelledByRequest            StatusCode = 0x805A0000
+	StatusBadParentNodeIDInvalid                  StatusCode = 0x805B0000
+	StatusBadReferenceNotAllowed                  StatusCode = 0x805C0000
+	StatusBadNodeIDRejected                       StatusCode = 0x805D0000
+	StatusBadNodeIDExists                         StatusCode = 0x805E0000
+	StatusBadNodeClassInvalid                     StatusCode = 0x805F0000
+	StatusBadBrowseNameInvalid                    StatusCode = 0x80600000
+	StatusBadBrowseNameDuplicated                 StatusCode = 0x80610000
+	StatusBadNodeAttributesInvalid                StatusCode = 0x80620000
+	StatusBadTypeDefinitionInvalid                StatusCode = 0x80630000
+	StatusBadSourceNodeIDInvalid                  StatusCode = 0x80640000
+	StatusBadTargetNodeIDInvalid                  StatusCode = 0x80650000
+	StatusBadDuplicateReferenceNotAllowed         StatusCode = 0x80660000
+	StatusBadInvalidSelfReference                 StatusCode = 0x80670000
+	StatusBadReferenceLocalOnly                   StatusCode = 0x80680000
+	StatusBadNoDeleteRights                       StatusCode = 0x80690000
+	StatusUncertainReferenceNotDeleted            StatusCode = 0x40BC0000
+	StatusBadServerIndexInvalid                   StatusCode = 0x806A0000
+	StatusBadViewIDUnknown                        StatusCode = 0x806B0000
+	StatusBadViewTimestampInvalid                 StatusCode = 0x80C90000
+	StatusBadViewParameterMismatch                StatusCode = 0x80CA0000
+	StatusBadViewVersionInvalid                   StatusCode = 0x80CB0000
+	StatusUncertainNotAllNodesAvailable           StatusCode = 0x40C00000
+	StatusGoodResultsMayBeIncomplete              StatusCode = 0x00BA0000
+	StatusBadNotTypeDefinition                    StatusCode = 0x80C80000
+	StatusUncertainReferenceOutOfServer           StatusCode = 0x406C0000
+	StatusBadTooManyMatches                       StatusCode = 0x806D0000
+	StatusBadQueryTooComplex                      StatusCode = 0x806E0000
+	StatusBadNoMatch                              StatusCode = 0x806F0000
+	StatusBadMaxAgeInvalid                        StatusCode = 0x80700000
+	StatusBadSecurityModeInsufficient             StatusCode = 0x80E60000
+	StatusBadHistoryOperationInvalid              StatusCode = 0x80710000
+	StatusBadHistoryOperationUnsupported          StatusCode = 0x80720000
+	StatusBadInvalidTimestampArgument             StatusCode = 0x80BD0000
+	StatusBadWriteNotSupported                    StatusCode = 0x80730000
+	StatusBadTypeMismatch                         StatusCode = 0x80740000
+	StatusBadMethodInvalid                        StatusCode = 0x80750000
+	StatusBadArgumentsMissing                     StatusCode = 0x80760000
+	StatusBadNotExecutable                        StatusCode = 0x81110000
+	StatusBadTooManySubscriptions                 StatusCode = 0x80770000
+	StatusBadTooManyPublishRequests               StatusCode = 0x80780000
+	StatusBadNoSubscription                       StatusCode = 0x80790000
+	StatusBadSequenceNumberUnknown                StatusCode = 0x807A0000
+	StatusBadMessageNotAvailable                  StatusCode = 0x807B0000
+	StatusBadInsufficientClientProfile            StatusCode = 0x807C0000
+	StatusBadStateNotActive                       StatusCode = 0x80BF0000
+	StatusBadAlreadyExists                        StatusCode = 0x81150000
+	StatusBadTcpServerTooBusy                     StatusCode = 0x807D0000
+	StatusBadTcpMessageTypeInvalid                StatusCode = 0x807E0000
+	StatusBadTcpSecureChannelUnknown              StatusCode = 0x807F0000
+	StatusBadTcpMessageTooLarge                   StatusCode = 0x80800000
+	StatusBadTcpNotEnoughResources                StatusCode = 0x80810000
+	StatusBadTcpInternalError                     StatusCode = 0x80820000
+	StatusBadTcpEndpointURLInvalid                StatusCode = 0x80830000
+	StatusBadRequestInterrupted                   StatusCode = 0x80840000
+	StatusBadRequestTimeout                       StatusCode = 0x80850000
+	StatusBadSecureChannelClosed                  StatusCode = 0x80860000
+	StatusBadSecureChannelTokenUnknown            StatusCode = 0x80870000
+	StatusBadSequenceNumberInvalid                StatusCode = 0x80880000
+	StatusBadProtocolVersionUnsupported           StatusCode = 0x80BE0000
+	StatusBadConfigurationError                   StatusCode = 0x80890000
+	StatusBadNotConnected                         StatusCode = 0x808A0000
+	StatusBadDeviceFailure                        StatusCode = 0x808B0000
+	StatusBadSensorFailure                        StatusCode = 0x808C0000
+	StatusBadOutOfService                         StatusCode = 0x808D0000
+	StatusBadDeadbandFilterInvalid                StatusCode = 0x808E0000
+	StatusUncertainNoCommunicationLastUsableValue StatusCode = 0x408F0000
+	StatusUncertainLastUsableValue                StatusCode = 0x40900000
+	StatusUncertainSubstituteValue                StatusCode = 0x40910000
+	StatusUncertainInitialValue                   StatusCode = 0x40920000
+	StatusUncertainSensorNotAccurate              StatusCode = 0x40930000
+	StatusUncertainEngineeringUnitsExceeded       StatusCode = 0x40940000
+	StatusUncertainSubNormal                      StatusCode = 0x40950000
+	StatusGoodLocalOverride                       StatusCode = 0x00960000
+	StatusBadRefreshInProgress                    StatusCode = 0x80970000
+	StatusBadConditionAlreadyDisabled             StatusCode = 0x80980000
+	StatusBadConditionAlreadyEnabled              StatusCode = 0x80CC0000
+	StatusBadConditionDisabled                    StatusCode = 0x80990000
+	StatusBadEventIDUnknown                       StatusCode = 0x809A0000
+	StatusBadEventNotAcknowledgeable              StatusCode = 0x80BB0000
+	StatusBadDialogNotActive                      StatusCode = 0x80CD0000
+	StatusBadDialogResponseInvalid                StatusCode = 0x80CE0000
+	StatusBadConditionBranchAlreadyAcked          StatusCode = 0x80CF0000
+	StatusBadConditionBranchAlreadyConfirmed      StatusCode = 0x80D00000
+	StatusBadConditionAlreadyShelved              StatusCode = 0x80D10000
+	StatusBadConditionNotShelved                  StatusCode = 0x80D20000
+	StatusBadShelvingTimeOutOfRange               StatusCode = 0x80D30000
+	StatusBadNoData                               StatusCode = 0x809B0000
+	StatusBadBoundNotFound                        StatusCode = 0x80D70000
+	StatusBadBoundNotSupported                    StatusCode = 0x80D80000
+	StatusBadDataLost                             StatusCode = 0x809D0000
+	StatusBadDataUnavailable                      StatusCode = 0x809E0000
+	StatusBadEntryExists                          StatusCode = 0x809F0000
+	StatusBadNoEntryExists                        StatusCode = 0x80A00000
+	StatusBadTimestampNotSupported                StatusCode = 0x80A10000
+	StatusGoodEntryInserted                       StatusCode = 0x00A20000
+	StatusGoodEntryReplaced                       StatusCode = 0x00A30000
+	StatusUncertainDataSubNormal                  StatusCode = 0x40A40000
+	StatusGoodNoData                              StatusCode = 0x00A50000
+	StatusGoodMoreData                            StatusCode = 0x00A60000
+	StatusBadAggregateListMismatch                StatusCode = 0x80D40000
+	StatusBadAggregateNotSupported                StatusCode = 0x80D50000
+	StatusBadAggregateInvalidInputs               StatusCode = 0x80D60000
+	StatusBadAggregateConfigurationRejected       StatusCode = 0x80DA0000
+	StatusGoodDataIgnored                         StatusCode = 0x00D90000
+	StatusBadRequestNotAllowed                    StatusCode = 0x80E40000
+	StatusBadRequestNotComplete                   StatusCode = 0x81130000
+	StatusGoodEdited                              StatusCode = 0x00DC0000
+	StatusGoodPostActionFailed                    StatusCode = 0x00DD0000
+	StatusUncertainDominantValueChanged           StatusCode = 0x40DE0000
+	StatusGoodDependentValueChanged               StatusCode = 0x00E00000
+	StatusBadDominantValueChanged                 StatusCode = 0x80E10000
+	StatusUncertainDependentValueChanged          StatusCode = 0x40E20000
+	StatusBadDependentValueChanged                StatusCode = 0x80E30000
+	StatusGoodCommunicationEvent                  StatusCode = 0x00A70000
+	StatusGoodShutdownEvent                       StatusCode = 0x00A80000
+	StatusGoodCallAgain                           StatusCode = 0x00A90000
+	StatusGoodNonCriticalTimeout                  StatusCode = 0x00AA0000
+	StatusBadInvalidArgument                      StatusCode = 0x80AB0000
+	StatusBadConnectionRejected                   StatusCode = 0x80AC0000
+	StatusBadDisconnect                           StatusCode = 0x80AD0000
+	StatusBadConnectionClosed                     StatusCode = 0x80AE0000
+	StatusBadInvalidState                         StatusCode = 0x80AF0000
+	StatusBadEndOfStream                          StatusCode = 0x80B00000
+	StatusBadNoDataAvailable                      StatusCode = 0x80B10000
+	StatusBadWaitingForResponse                   StatusCode = 0x80B20000
+	StatusBadOperationAbandoned                   StatusCode = 0x80B30000
+	StatusBadExpectedStreamToBlock                StatusCode = 0x80B40000
+	StatusBadWouldBlock                           StatusCode = 0x80B50000
+	StatusBadSyntaxError                          StatusCode = 0x80B60000
+	StatusBadMaxConnectionsReached                StatusCode = 0x80B70000
+)
+
+type StatusCodeDesc struct {
+	Name string
+	Text string
+}
+
+// StatusCodes maps status codes to the status code error types.
+var StatusCodes = map[StatusCode]StatusCodeDesc{
+	StatusOK:                                      StatusCodeDesc{Name: "OK", Text: "OK"},
+	StatusBadUnexpectedError:                      StatusCodeDesc{Name: "StatusBadUnexpectedError", Text: "An unexpected error occurred."},
+	StatusBadInternalError:                        StatusCodeDesc{Name: "StatusBadInternalError", Text: "An internal error occurred as a result of a programming or configuration error."},
+	StatusBadOutOfMemory:                          StatusCodeDesc{Name: "StatusBadOutOfMemory", Text: "Not enough memory to complete the operation."},
+	StatusBadResourceUnavailable:                  StatusCodeDesc{Name: "StatusBadResourceUnavailable", Text: "An operating system resource is not available."},
+	StatusBadCommunicationError:                   StatusCodeDesc{Name: "StatusBadCommunicationError", Text: "A low level communication error occurred."},
+	StatusBadEncodingError:                        StatusCodeDesc{Name: "StatusBadEncodingError", Text: "Encoding halted because of invalid data in the objects being serialized."},
+	StatusBadDecodingError:                        StatusCodeDesc{Name: "StatusBadDecodingError", Text: "Decoding halted because of invalid data in the stream."},
+	StatusBadEncodingLimitsExceeded:               StatusCodeDesc{Name: "StatusBadEncodingLimitsExceeded", Text: "The message encoding/decoding limits imposed by the stack have been exceeded."},
+	StatusBadRequestTooLarge:                      StatusCodeDesc{Name: "StatusBadRequestTooLarge", Text: "The request message size exceeds limits set by the server."},
+	StatusBadResponseTooLarge:                     StatusCodeDesc{Name: "StatusBadResponseTooLarge", Text: "The response message size exceeds limits set by the client."},
+	StatusBadUnknownResponse:                      StatusCodeDesc{Name: "StatusBadUnknownResponse", Text: "An unrecognized response was received from the server."},
+	StatusBadTimeout:                              StatusCodeDesc{Name: "StatusBadTimeout", Text: "The operation timed out."},
+	StatusBadServiceUnsupported:                   StatusCodeDesc{Name: "StatusBadServiceUnsupported", Text: "The server does not support the requested service."},
+	StatusBadShutdown:                             StatusCodeDesc{Name: "StatusBadShutdown", Text: "The operation was cancelled because the application is shutting down."},
+	StatusBadServerNotConnected:                   StatusCodeDesc{Name: "StatusBadServerNotConnected", Text: "The operation could not complete because the client is not connected to the server."},
+	StatusBadServerHalted:                         StatusCodeDesc{Name: "StatusBadServerHalted", Text: "The server has stopped and cannot process any requests."},
+	StatusBadNothingToDo:                          StatusCodeDesc{Name: "StatusBadNothingToDo", Text: "There was nothing to do because the client passed a list of operations with no elements."},
+	StatusBadTooManyOperations:                    StatusCodeDesc{Name: "StatusBadTooManyOperations", Text: "The request could not be processed because it specified too many operations."},
+	StatusBadTooManyMonitoredItems:                StatusCodeDesc{Name: "StatusBadTooManyMonitoredItems", Text: "The request could not be processed because there are too many monitored items in the subscription."},
+	StatusBadDataTypeIDUnknown:                    StatusCodeDesc{Name: "StatusBadDataTypeIDUnknown", Text: "The extension object cannot be (de)serialized because the data type id is not recognized."},
+	StatusBadCertificateInvalid:                   StatusCodeDesc{Name: "StatusBadCertificateInvalid", Text: "The certificate provided as a parameter is not valid."},
+	StatusBadSecurityChecksFailed:                 StatusCodeDesc{Name: "StatusBadSecurityChecksFailed", Text: "An error occurred verifying security."},
+	StatusBadCertificatePolicyCheckFailed:         StatusCodeDesc{Name: "StatusBadCertificatePolicyCheckFailed", Text: "The certificate does not meet the requirements of the security policy."},
+	StatusBadCertificateTimeInvalid:               StatusCodeDesc{Name: "StatusBadCertificateTimeInvalid", Text: "The certificate has expired or is not yet valid."},
+	StatusBadCertificateIssuerTimeInvalid:         StatusCodeDesc{Name: "StatusBadCertificateIssuerTimeInvalid", Text: "An issuer certificate has expired or is not yet valid."},
+	StatusBadCertificateHostNameInvalid:           StatusCodeDesc{Name: "StatusBadCertificateHostNameInvalid", Text: "The HostName used to connect to a server does not match a HostName in the certificate."},
+	StatusBadCertificateURIInvalid:                StatusCodeDesc{Name: "StatusBadCertificateURIInvalid", Text: "The URI specified in the ApplicationDescription does not match the URI in the certificate."},
+	StatusBadCertificateUseNotAllowed:             StatusCodeDesc{Name: "StatusBadCertificateUseNotAllowed", Text: "The certificate may not be used for the requested operation."},
+	StatusBadCertificateIssuerUseNotAllowed:       StatusCodeDesc{Name: "StatusBadCertificateIssuerUseNotAllowed", Text: "The issuer certificate may not be used for the requested operation."},
+	StatusBadCertificateUntrusted:                 StatusCodeDesc{Name: "StatusBadCertificateUntrusted", Text: "The certificate is not trusted."},
+	StatusBadCertificateRevocationUnknown:         StatusCodeDesc{Name: "StatusBadCertificateRevocationUnknown", Text: "It was not possible to determine if the certificate has been revoked."},
+	StatusBadCertificateIssuerRevocationUnknown:   StatusCodeDesc{Name: "StatusBadCertificateIssuerRevocationUnknown", Text: "It was not possible to determine if the issuer certificate has been revoked."},
+	StatusBadCertificateRevoked:                   StatusCodeDesc{Name: "StatusBadCertificateRevoked", Text: "The certificate has been revoked."},
+	StatusBadCertificateIssuerRevoked:             StatusCodeDesc{Name: "StatusBadCertificateIssuerRevoked", Text: "The issuer certificate has been revoked."},
+	StatusBadCertificateChainIncomplete:           StatusCodeDesc{Name: "StatusBadCertificateChainIncomplete", Text: "The certificate chain is incomplete."},
+	StatusBadUserAccessDenied:                     StatusCodeDesc{Name: "StatusBadUserAccessDenied", Text: "User does not have permission to perform the requested operation."},
+	StatusBadIdentityTokenInvalid:                 StatusCodeDesc{Name: "StatusBadIdentityTokenInvalid", Text: "The user identity token is not valid."},
+	StatusBadIdentityTokenRejected:                StatusCodeDesc{Name: "StatusBadIdentityTokenRejected", Text: "The user identity token is valid but the server has rejected it."},
+	StatusBadSecureChannelIDInvalid:               StatusCodeDesc{Name: "StatusBadSecureChannelIDInvalid", Text: "The specified secure channel is no longer valid."},
+	StatusBadInvalidTimestamp:                     StatusCodeDesc{Name: "StatusBadInvalidTimestamp", Text: "The timestamp is outside the range allowed by the server."},
+	StatusBadNonceInvalid:                         StatusCodeDesc{Name: "StatusBadNonceInvalid", Text: "The nonce does appear to be not a random value or it is not the correct length."},
+	StatusBadSessionIDInvalid:                     StatusCodeDesc{Name: "StatusBadSessionIDInvalid", Text: "The session id is not valid."},
+	StatusBadSessionClosed:                        StatusCodeDesc{Name: "StatusBadSessionClosed", Text: "The session was closed by the client."},
+	StatusBadSessionNotActivated:                  StatusCodeDesc{Name: "StatusBadSessionNotActivated", Text: "The session cannot be used because ActivateSession has not been called."},
+	StatusBadSubscriptionIDInvalid:                StatusCodeDesc{Name: "StatusBadSubscriptionIDInvalid", Text: "The subscription id is not valid."},
+	StatusBadRequestHeaderInvalid:                 StatusCodeDesc{Name: "StatusBadRequestHeaderInvalid", Text: "The header for the request is missing or invalid."},
+	StatusBadTimestampsToReturnInvalid:            StatusCodeDesc{Name: "StatusBadTimestampsToReturnInvalid", Text: "The timestamps to return parameter is invalid."},
+	StatusBadRequestCancelledByClient:             StatusCodeDesc{Name: "StatusBadRequestCancelledByClient", Text: "The request was cancelled by the client."},
+	StatusBadTooManyArguments:                     StatusCodeDesc{Name: "StatusBadTooManyArguments", Text: "Too many arguments were provided."},
+	StatusBadLicenseExpired:                       StatusCodeDesc{Name: "StatusBadLicenseExpired", Text: "The server requires a license to operate in general or to perform a service or operation, but existing license is expired."},
+	StatusBadLicenseLimitsExceeded:                StatusCodeDesc{Name: "StatusBadLicenseLimitsExceeded", Text: "The server has limits on number of allowed operations / objects, based on installed licenses, and these limits where exceeded."},
+	StatusBadLicenseNotAvailable:                  StatusCodeDesc{Name: "StatusBadLicenseNotAvailable", Text: "The server does not have a license which is required to operate in general or to perform a service or operation."},
+	StatusGoodSubscriptionTransferred:             StatusCodeDesc{Name: "StatusGoodSubscriptionTransferred", Text: "The subscription was transferred to another session."},
+	StatusGoodCompletesAsynchronously:             StatusCodeDesc{Name: "StatusGoodCompletesAsynchronously", Text: "The processing will complete asynchronously."},
+	StatusGoodOverload:                            StatusCodeDesc{Name: "StatusGoodOverload", Text: "Sampling has slowed down due to resource limitations."},
+	StatusGoodClamped:                             StatusCodeDesc{Name: "StatusGoodClamped", Text: "The value written was accepted but was clamped."},
+	StatusBadNoCommunication:                      StatusCodeDesc{Name: "StatusBadNoCommunication", Text: "Communication with the data source is defined, but not established, and there is no last known value available."},
+	StatusBadWaitingForInitialData:                StatusCodeDesc{Name: "StatusBadWaitingForInitialData", Text: "Waiting for the server to obtain values from the underlying data source."},
+	StatusBadNodeIDInvalid:                        StatusCodeDesc{Name: "StatusBadNodeIDInvalid", Text: "The syntax of the node id is not valid."},
+	StatusBadNodeIDUnknown:                        StatusCodeDesc{Name: "StatusBadNodeIDUnknown", Text: "The node id refers to a node that does not exist in the server address space."},
+	StatusBadAttributeIDInvalid:                   StatusCodeDesc{Name: "StatusBadAttributeIDInvalid", Text: "The attribute is not supported for the specified Node."},
+	StatusBadIndexRangeInvalid:                    StatusCodeDesc{Name: "StatusBadIndexRangeInvalid", Text: "The syntax of the index range parameter is invalid."},
+	StatusBadIndexRangeNoData:                     StatusCodeDesc{Name: "StatusBadIndexRangeNoData", Text: "No data exists within the range of indexes specified."},
+	StatusBadDataEncodingInvalid:                  StatusCodeDesc{Name: "StatusBadDataEncodingInvalid", Text: "The data encoding is invalid."},
+	StatusBadDataEncodingUnsupported:              StatusCodeDesc{Name: "StatusBadDataEncodingUnsupported", Text: "The server does not support the requested data encoding for the node."},
+	StatusBadNotReadable:                          StatusCodeDesc{Name: "StatusBadNotReadable", Text: "The access level does not allow reading or subscribing to the Node."},
+	StatusBadNotWritable:                          StatusCodeDesc{Name: "StatusBadNotWritable", Text: "The access level does not allow writing to the Node."},
+	StatusBadOutOfRange:                           StatusCodeDesc{Name: "StatusBadOutOfRange", Text: "The value was out of range."},
+	StatusBadNotSupported:                         StatusCodeDesc{Name: "StatusBadNotSupported", Text: "The requested operation is not supported."},
+	StatusBadNotFound:                             StatusCodeDesc{Name: "StatusBadNotFound", Text: "A requested item was not found or a search operation ended without success."},
+	StatusBadObjectDeleted:                        StatusCodeDesc{Name: "StatusBadObjectDeleted", Text: "The object cannot be used because it has been deleted."},
+	StatusBadNotImplemented:                       StatusCodeDesc{Name: "StatusBadNotImplemented", Text: "Requested operation is not implemented."},
+	StatusBadMonitoringModeInvalid:                StatusCodeDesc{Name: "StatusBadMonitoringModeInvalid", Text: "The monitoring mode is invalid."},
+	StatusBadMonitoredItemIDInvalid:               StatusCodeDesc{Name: "StatusBadMonitoredItemIDInvalid", Text: "The monitoring item id does not refer to a valid monitored item."},
+	StatusBadMonitoredItemFilterInvalid:           StatusCodeDesc{Name: "StatusBadMonitoredItemFilterInvalid", Text: "The monitored item filter parameter is not valid."},
+	StatusBadMonitoredItemFilterUnsupported:       StatusCodeDesc{Name: "StatusBadMonitoredItemFilterUnsupported", Text: "The server does not support the requested monitored item filter."},
+	StatusBadFilterNotAllowed:                     StatusCodeDesc{Name: "StatusBadFilterNotAllowed", Text: "A monitoring filter cannot be used in combination with the attribute specified."},
+	StatusBadStructureMissing:                     StatusCodeDesc{Name: "StatusBadStructureMissing", Text: "A mandatory structured parameter was missing or null."},
+	StatusBadEventFilterInvalid:                   StatusCodeDesc{Name: "StatusBadEventFilterInvalid", Text: "The event filter is not valid."},
+	StatusBadContentFilterInvalid:                 StatusCodeDesc{Name: "StatusBadContentFilterInvalid", Text: "The content filter is not valid."},
+	StatusBadFilterOperatorInvalid:                StatusCodeDesc{Name: "StatusBadFilterOperatorInvalid", Text: "An unrecognized operator was provided in a filter."},
+	StatusBadFilterOperatorUnsupported:            StatusCodeDesc{Name: "StatusBadFilterOperatorUnsupported", Text: "A valid operator was provided, but the server does not provide support for this filter operator."},
+	StatusBadFilterOperandCountMismatch:           StatusCodeDesc{Name: "StatusBadFilterOperandCountMismatch", Text: "The number of operands provided for the filter operator was less then expected for the operand provided."},
+	StatusBadFilterOperandInvalid:                 StatusCodeDesc{Name: "StatusBadFilterOperandInvalid", Text: "The operand used in a content filter is not valid."},
+	StatusBadFilterElementInvalid:                 StatusCodeDesc{Name: "StatusBadFilterElementInvalid", Text: "The referenced element is not a valid element in the content filter."},
+	StatusBadFilterLiteralInvalid:                 StatusCodeDesc{Name: "StatusBadFilterLiteralInvalid", Text: "The referenced literal is not a valid value."},
+	StatusBadContinuationPointInvalid:             StatusCodeDesc{Name: "StatusBadContinuationPointInvalid", Text: "The continuation point provide is longer valid."},
+	StatusBadNoContinuationPoints:                 StatusCodeDesc{Name: "StatusBadNoContinuationPoints", Text: "The operation could not be processed because all continuation points have been allocated."},
+	StatusBadReferenceTypeIDInvalid:               StatusCodeDesc{Name: "StatusBadReferenceTypeIDInvalid", Text: "The reference type id does not refer to a valid reference type node."},
+	StatusBadBrowseDirectionInvalid:               StatusCodeDesc{Name: "StatusBadBrowseDirectionInvalid", Text: "The browse direction is not valid."},
+	StatusBadNodeNotInView:                        StatusCodeDesc{Name: "StatusBadNodeNotInView", Text: "The node is not part of the view."},
+	StatusBadNumericOverflow:                      StatusCodeDesc{Name: "StatusBadNumericOverflow", Text: "The number was not accepted because of a numeric overflow."},
+	StatusBadServerURIInvalid:                     StatusCodeDesc{Name: "StatusBadServerURIInvalid", Text: "The ServerUri is not a valid URI."},
+	StatusBadServerNameMissing:                    StatusCodeDesc{Name: "StatusBadServerNameMissing", Text: "No ServerName was specified."},
+	StatusBadDiscoveryURLMissing:                  StatusCodeDesc{Name: "StatusBadDiscoveryURLMissing", Text: "No DiscoveryUrl was specified."},
+	StatusBadSempahoreFileMissing:                 StatusCodeDesc{Name: "StatusBadSempahoreFileMissing", Text: "The semaphore file specified by the client is not valid."},
+	StatusBadRequestTypeInvalid:                   StatusCodeDesc{Name: "StatusBadRequestTypeInvalid", Text: "The security token request type is not valid."},
+	StatusBadSecurityModeRejected:                 StatusCodeDesc{Name: "StatusBadSecurityModeRejected", Text: "The security mode does not meet the requirements set by the server."},
+	StatusBadSecurityPolicyRejected:               StatusCodeDesc{Name: "StatusBadSecurityPolicyRejected", Text: "The security policy does not meet the requirements set by the server."},
+	StatusBadTooManySessions:                      StatusCodeDesc{Name: "StatusBadTooManySessions", Text: "The server has reached its maximum number of sessions."},
+	StatusBadUserSignatureInvalid:                 StatusCodeDesc{Name: "StatusBadUserSignatureInvalid", Text: "The user token signature is missing or invalid."},
+	StatusBadApplicationSignatureInvalid:          StatusCodeDesc{Name: "StatusBadApplicationSignatureInvalid", Text: "The signature generated with the client certificate is missing or invalid."},
+	StatusBadNoValidCertificates:                  StatusCodeDesc{Name: "StatusBadNoValidCertificates", Text: "The client did not provide at least one software certificate that is valid and meets the profile requirements for the server."},
+	StatusBadIdentityChangeNotSupported:           StatusCodeDesc{Name: "StatusBadIdentityChangeNotSupported", Text: "The server does not support changing the user identity assigned to the session."},
+	StatusBadRequestCancelledByRequest:            StatusCodeDesc{Name: "StatusBadRequestCancelledByRequest", Text: "The request was cancelled by the client with the Cancel service."},
+	StatusBadParentNodeIDInvalid:                  StatusCodeDesc{Name: "StatusBadParentNodeIDInvalid", Text: "The parent node id does not to refer to a valid node."},
+	StatusBadReferenceNotAllowed:                  StatusCodeDesc{Name: "StatusBadReferenceNotAllowed", Text: "The reference could not be created because it violates constraints imposed by the data model."},
+	StatusBadNodeIDRejected:                       StatusCodeDesc{Name: "StatusBadNodeIDRejected", Text: "The requested node id was reject because it was either invalid or server does not allow node ids to be specified by the client."},
+	StatusBadNodeIDExists:                         StatusCodeDesc{Name: "StatusBadNodeIDExists", Text: "The requested node id is already used by another node."},
+	StatusBadNodeClassInvalid:                     StatusCodeDesc{Name: "StatusBadNodeClassInvalid", Text: "The node class is not valid."},
+	StatusBadBrowseNameInvalid:                    StatusCodeDesc{Name: "StatusBadBrowseNameInvalid", Text: "The browse name is invalid."},
+	StatusBadBrowseNameDuplicated:                 StatusCodeDesc{Name: "StatusBadBrowseNameDuplicated", Text: "The browse name is not unique among nodes that share the same relationship with the parent."},
+	StatusBadNodeAttributesInvalid:                StatusCodeDesc{Name: "StatusBadNodeAttributesInvalid", Text: "The node attributes are not valid for the node class."},
+	StatusBadTypeDefinitionInvalid:                StatusCodeDesc{Name: "StatusBadTypeDefinitionInvalid", Text: "The type definition node id does not reference an appropriate type node."},
+	StatusBadSourceNodeIDInvalid:                  StatusCodeDesc{Name: "StatusBadSourceNodeIDInvalid", Text: "The source node id does not reference a valid node."},
+	StatusBadTargetNodeIDInvalid:                  StatusCodeDesc{Name: "StatusBadTargetNodeIDInvalid", Text: "The target node id does not reference a valid node."},
+	StatusBadDuplicateReferenceNotAllowed:         StatusCodeDesc{Name: "StatusBadDuplicateReferenceNotAllowed", Text: "The reference type between the nodes is already defined."},
+	StatusBadInvalidSelfReference:                 StatusCodeDesc{Name: "StatusBadInvalidSelfReference", Text: "The server does not allow this type of self reference on this node."},
+	StatusBadReferenceLocalOnly:                   StatusCodeDesc{Name: "StatusBadReferenceLocalOnly", Text: "The reference type is not valid for a reference to a remote server."},
+	StatusBadNoDeleteRights:                       StatusCodeDesc{Name: "StatusBadNoDeleteRights", Text: "The server will not allow the node to be deleted."},
+	StatusUncertainReferenceNotDeleted:            StatusCodeDesc{Name: "StatusUncertainReferenceNotDeleted", Text: "The server was not able to delete all target references."},
+	StatusBadServerIndexInvalid:                   StatusCodeDesc{Name: "StatusBadServerIndexInvalid", Text: "The server index is not valid."},
+	StatusBadViewIDUnknown:                        StatusCodeDesc{Name: "StatusBadViewIDUnknown", Text: "The view id does not refer to a valid view node."},
+	StatusBadViewTimestampInvalid:                 StatusCodeDesc{Name: "StatusBadViewTimestampInvalid", Text: "The view timestamp is not available or not supported."},
+	StatusBadViewParameterMismatch:                StatusCodeDesc{Name: "StatusBadViewParameterMismatch", Text: "The view parameters are not consistent with each other."},
+	StatusBadViewVersionInvalid:                   StatusCodeDesc{Name: "StatusBadViewVersionInvalid", Text: "The view version is not available or not supported."},
+	StatusUncertainNotAllNodesAvailable:           StatusCodeDesc{Name: "StatusUncertainNotAllNodesAvailable", Text: "The list of references may not be complete because the underlying system is not available."},
+	StatusGoodResultsMayBeIncomplete:              StatusCodeDesc{Name: "StatusGoodResultsMayBeIncomplete", Text: "The server should have followed a reference to a node in a remote server but did not. The result set may be incomplete."},
+	StatusBadNotTypeDefinition:                    StatusCodeDesc{Name: "StatusBadNotTypeDefinition", Text: "The provided Nodeid was not a type definition nodeid."},
+	StatusUncertainReferenceOutOfServer:           StatusCodeDesc{Name: "StatusUncertainReferenceOutOfServer", Text: "One of the references to follow in the relative path references to a node in the address space in another server."},
+	StatusBadTooManyMatches:                       StatusCodeDesc{Name: "StatusBadTooManyMatches", Text: "The requested operation has too many matches to return."},
+	StatusBadQueryTooComplex:                      StatusCodeDesc{Name: "StatusBadQueryTooComplex", Text: "The requested operation requires too many resources in the server."},
+	StatusBadNoMatch:                              StatusCodeDesc{Name: "StatusBadNoMatch", Text: "The requested operation has no match to return."},
+	StatusBadMaxAgeInvalid:                        StatusCodeDesc{Name: "StatusBadMaxAgeInvalid", Text: "The max age parameter is invalid."},
+	StatusBadSecurityModeInsufficient:             StatusCodeDesc{Name: "StatusBadSecurityModeInsufficient", Text: "The operation is not permitted over the current secure channel."},
+	StatusBadHistoryOperationInvalid:              StatusCodeDesc{Name: "StatusBadHistoryOperationInvalid", Text: "The history details parameter is not valid."},
+	StatusBadHistoryOperationUnsupported:          StatusCodeDesc{Name: "StatusBadHistoryOperationUnsupported", Text: "The server does not support the requested operation."},
+	StatusBadInvalidTimestampArgument:             StatusCodeDesc{Name: "StatusBadInvalidTimestampArgument", Text: "The defined timestamp to return was invalid."},
+	StatusBadWriteNotSupported:                    StatusCodeDesc{Name: "StatusBadWriteNotSupported", Text: "The server does not support writing the combination of value, status and timestamps provided."},
+	StatusBadTypeMismatch:                         StatusCodeDesc{Name: "StatusBadTypeMismatch", Text: "The value supplied for the attribute is not of the same type as the attribute's value."},
+	StatusBadMethodInvalid:                        StatusCodeDesc{Name: "StatusBadMethodInvalid", Text: "The method id does not refer to a method for the specified object."},
+	StatusBadArgumentsMissing:                     StatusCodeDesc{Name: "StatusBadArgumentsMissing", Text: "The client did not specify all of the input arguments for the method."},
+	StatusBadNotExecutable:                        StatusCodeDesc{Name: "StatusBadNotExecutable", Text: "The executable attribute does not allow the execution of the method."},
+	StatusBadTooManySubscriptions:                 StatusCodeDesc{Name: "StatusBadTooManySubscriptions", Text: "The server has reached its maximum number of subscriptions."},
+	StatusBadTooManyPublishRequests:               StatusCodeDesc{Name: "StatusBadTooManyPublishRequests", Text: "The server has reached the maximum number of queued publish requests."},
+	StatusBadNoSubscription:                       StatusCodeDesc{Name: "StatusBadNoSubscription", Text: "There is no subscription available for this session."},
+	StatusBadSequenceNumberUnknown:                StatusCodeDesc{Name: "StatusBadSequenceNumberUnknown", Text: "The sequence number is unknown to the server."},
+	StatusBadMessageNotAvailable:                  StatusCodeDesc{Name: "StatusBadMessageNotAvailable", Text: "The requested notification message is no longer available."},
+	StatusBadInsufficientClientProfile:            StatusCodeDesc{Name: "StatusBadInsufficientClientProfile", Text: "The client of the current session does not support one or more Profiles that are necessary for the subscription."},
+	StatusBadStateNotActive:                       StatusCodeDesc{Name: "StatusBadStateNotActive", Text: "The sub-state machine is not currently active."},
+	StatusBadAlreadyExists:                        StatusCodeDesc{Name: "StatusBadAlreadyExists", Text: "An equivalent rule already exists."},
+	StatusBadTcpServerTooBusy:                     StatusCodeDesc{Name: "StatusBadTcpServerTooBusy", Text: "The server cannot process the request because it is too busy."},
+	StatusBadTcpMessageTypeInvalid:                StatusCodeDesc{Name: "StatusBadTcpMessageTypeInvalid", Text: "The type of the message specified in the header invalid."},
+	StatusBadTcpSecureChannelUnknown:              StatusCodeDesc{Name: "StatusBadTcpSecureChannelUnknown", Text: "The SecureChannelId and/or TokenId are not currently in use."},
+	StatusBadTcpMessageTooLarge:                   StatusCodeDesc{Name: "StatusBadTcpMessageTooLarge", Text: "The size of the message specified in the header is too large."},
+	StatusBadTcpNotEnoughResources:                StatusCodeDesc{Name: "StatusBadTcpNotEnoughResources", Text: "There are not enough resources to process the request."},
+	StatusBadTcpInternalError:                     StatusCodeDesc{Name: "StatusBadTcpInternalError", Text: "An internal error occurred."},
+	StatusBadTcpEndpointURLInvalid:                StatusCodeDesc{Name: "StatusBadTcpEndpointURLInvalid", Text: "The server does not recognize the QueryString specified."},
+	StatusBadRequestInterrupted:                   StatusCodeDesc{Name: "StatusBadRequestInterrupted", Text: "The request could not be sent because of a network interruption."},
+	StatusBadRequestTimeout:                       StatusCodeDesc{Name: "StatusBadRequestTimeout", Text: "Timeout occurred while processing the request."},
+	StatusBadSecureChannelClosed:                  StatusCodeDesc{Name: "StatusBadSecureChannelClosed", Text: "The secure channel has been closed."},
+	StatusBadSecureChannelTokenUnknown:            StatusCodeDesc{Name: "StatusBadSecureChannelTokenUnknown", Text: "The token has expired or is not recognized."},
+	StatusBadSequenceNumberInvalid:                StatusCodeDesc{Name: "StatusBadSequenceNumberInvalid", Text: "The sequence number is not valid."},
+	StatusBadProtocolVersionUnsupported:           StatusCodeDesc{Name: "StatusBadProtocolVersionUnsupported", Text: "The applications do not have compatible protocol versions."},
+	StatusBadConfigurationError:                   StatusCodeDesc{Name: "StatusBadConfigurationError", Text: "There is a problem with the configuration that affects the usefulness of the value."},
+	StatusBadNotConnected:                         StatusCodeDesc{Name: "StatusBadNotConnected", Text: "The variable should receive its value from another variable, but has never been configured to do so."},
+	StatusBadDeviceFailure:                        StatusCodeDesc{Name: "StatusBadDeviceFailure", Text: "There has been a failure in the device/data source that generates the value that has affected the value."},
+	StatusBadSensorFailure:                        StatusCodeDesc{Name: "StatusBadSensorFailure", Text: "There has been a failure in the sensor from which the value is derived by the device/data source."},
+	StatusBadOutOfService:                         StatusCodeDesc{Name: "StatusBadOutOfService", Text: "The source of the data is not operational."},
+	StatusBadDeadbandFilterInvalid:                StatusCodeDesc{Name: "StatusBadDeadbandFilterInvalid", Text: "The deadband filter is not valid."},
+	StatusUncertainNoCommunicationLastUsableValue: StatusCodeDesc{Name: "StatusUncertainNoCommunicationLastUsableValue", Text: "Communication to the data source has failed. The variable value is the last value that had a good quality."},
+	StatusUncertainLastUsableValue:                StatusCodeDesc{Name: "StatusUncertainLastUsableValue", Text: "Whatever was updating this value has stopped doing so."},
+	StatusUncertainSubstituteValue:                StatusCodeDesc{Name: "StatusUncertainSubstituteValue", Text: "The value is an operational value that was manually overwritten."},
+	StatusUncertainInitialValue:                   StatusCodeDesc{Name: "StatusUncertainInitialValue", Text: "The value is an initial value for a variable that normally receives its value from another variable."},
+	StatusUncertainSensorNotAccurate:              StatusCodeDesc{Name: "StatusUncertainSensorNotAccurate", Text: "The value is at one of the sensor limits."},
+	StatusUncertainEngineeringUnitsExceeded:       StatusCodeDesc{Name: "StatusUncertainEngineeringUnitsExceeded", Text: "The value is outside of the range of values defined for this parameter."},
+	StatusUncertainSubNormal:                      StatusCodeDesc{Name: "StatusUncertainSubNormal", Text: "The value is derived from multiple sources and has less than the required number of Good sources."},
+	StatusGoodLocalOverride:                       StatusCodeDesc{Name: "StatusGoodLocalOverride", Text: "The value has been overridden."},
+	StatusBadRefreshInProgress:                    StatusCodeDesc{Name: "StatusBadRefreshInProgress", Text: "This Condition refresh failed, a Condition refresh operation is already in progress."},
+	StatusBadConditionAlreadyDisabled:             StatusCodeDesc{Name: "StatusBadConditionAlreadyDisabled", Text: "This condition has already been disabled."},
+	StatusBadConditionAlreadyEnabled:              StatusCodeDesc{Name: "StatusBadConditionAlreadyEnabled", Text: "This condition has already been enabled."},
+	StatusBadConditionDisabled:                    StatusCodeDesc{Name: "StatusBadConditionDisabled", Text: "Property not available, this condition is disabled."},
+	StatusBadEventIDUnknown:                       StatusCodeDesc{Name: "StatusBadEventIDUnknown", Text: "The specified event id is not recognized."},
+	StatusBadEventNotAcknowledgeable:              StatusCodeDesc{Name: "StatusBadEventNotAcknowledgeable", Text: "The event cannot be acknowledged."},
+	StatusBadDialogNotActive:                      StatusCodeDesc{Name: "StatusBadDialogNotActive", Text: "The dialog condition is not active."},
+	StatusBadDialogResponseInvalid:                StatusCodeDesc{Name: "StatusBadDialogResponseInvalid", Text: "The response is not valid for the dialog."},
+	StatusBadConditionBranchAlreadyAcked:          StatusCodeDesc{Name: "StatusBadConditionBranchAlreadyAcked", Text: "The condition branch has already been acknowledged."},
+	StatusBadConditionBranchAlreadyConfirmed:      StatusCodeDesc{Name: "StatusBadConditionBranchAlreadyConfirmed", Text: "The condition branch has already been confirmed."},
+	StatusBadConditionAlreadyShelved:              StatusCodeDesc{Name: "StatusBadConditionAlreadyShelved", Text: "The condition has already been shelved."},
+	StatusBadConditionNotShelved:                  StatusCodeDesc{Name: "StatusBadConditionNotShelved", Text: "The condition is not currently shelved."},
+	StatusBadShelvingTimeOutOfRange:               StatusCodeDesc{Name: "StatusBadShelvingTimeOutOfRange", Text: "The shelving time not within an acceptable range."},
+	StatusBadNoData:                               StatusCodeDesc{Name: "StatusBadNoData", Text: "No data exists for the requested time range or event filter."},
+	StatusBadBoundNotFound:                        StatusCodeDesc{Name: "StatusBadBoundNotFound", Text: "No data found to provide upper or lower bound value."},
+	StatusBadBoundNotSupported:                    StatusCodeDesc{Name: "StatusBadBoundNotSupported", Text: "The server cannot retrieve a bound for the variable."},
+	StatusBadDataLost:                             StatusCodeDesc{Name: "StatusBadDataLost", Text: "Data is missing due to collection started/stopped/lost."},
+	StatusBadDataUnavailable:                      StatusCodeDesc{Name: "StatusBadDataUnavailable", Text: "Expected data is unavailable for the requested time range due to an un-mounted volume, an off-line archive or tape, or similar reason for temporary unavailability."},
+	StatusBadEntryExists:                          StatusCodeDesc{Name: "StatusBadEntryExists", Text: "The data or event was not successfully inserted because a matching entry exists."},
+	StatusBadNoEntryExists:                        StatusCodeDesc{Name: "StatusBadNoEntryExists", Text: "The data or event was not successfully updated because no matching entry exists."},
+	StatusBadTimestampNotSupported:                StatusCodeDesc{Name: "StatusBadTimestampNotSupported", Text: "The client requested history using a timestamp format the server does not support (i.e requested ServerTimestamp when server only supports SourceTimestamp)."},
+	StatusGoodEntryInserted:                       StatusCodeDesc{Name: "StatusGoodEntryInserted", Text: "The data or event was successfully inserted into the historical database."},
+	StatusGoodEntryReplaced:                       StatusCodeDesc{Name: "StatusGoodEntryReplaced", Text: "The data or event field was successfully replaced in the historical database."},
+	StatusUncertainDataSubNormal:                  StatusCodeDesc{Name: "StatusUncertainDataSubNormal", Text: "The value is derived from multiple values and has less than the required number of Good values."},
+	StatusGoodNoData:                              StatusCodeDesc{Name: "StatusGoodNoData", Text: "No data exists for the requested time range or event filter."},
+	StatusGoodMoreData:                            StatusCodeDesc{Name: "StatusGoodMoreData", Text: "The data or event field was successfully replaced in the historical database."},
+	StatusBadAggregateListMismatch:                StatusCodeDesc{Name: "StatusBadAggregateListMismatch", Text: "The requested number of Aggregates does not match the requested number of NodeIds."},
+	StatusBadAggregateNotSupported:                StatusCodeDesc{Name: "StatusBadAggregateNotSupported", Text: "The requested Aggregate is not support by the server."},
+	StatusBadAggregateInvalidInputs:               StatusCodeDesc{Name: "StatusBadAggregateInvalidInputs", Text: "The aggregate value could not be derived due to invalid data inputs."},
+	StatusBadAggregateConfigurationRejected:       StatusCodeDesc{Name: "StatusBadAggregateConfigurationRejected", Text: "The aggregate configuration is not valid for specified node."},
+	StatusGoodDataIgnored:                         StatusCodeDesc{Name: "StatusGoodDataIgnored", Text: "The request specifies fields which are not valid for the EventType or cannot be saved by the historian."},
+	StatusBadRequestNotAllowed:                    StatusCodeDesc{Name: "StatusBadRequestNotAllowed", Text: "The request was rejected by the server because it did not meet the criteria set by the server."},
+	StatusBadRequestNotComplete:                   StatusCodeDesc{Name: "StatusBadRequestNotComplete", Text: "The request has not been processed by the server yet."},
+	StatusGoodEdited:                              StatusCodeDesc{Name: "StatusGoodEdited", Text: "The value does not come from the real source and has been edited by the server."},
+	StatusGoodPostActionFailed:                    StatusCodeDesc{Name: "StatusGoodPostActionFailed", Text: "There was an error in execution of these post-actions."},
+	StatusUncertainDominantValueChanged:           StatusCodeDesc{Name: "StatusUncertainDominantValueChanged", Text: "The related EngineeringUnit has been changed but the Variable Value is still provided based on the previous unit."},
+	StatusGoodDependentValueChanged:               StatusCodeDesc{Name: "StatusGoodDependentValueChanged", Text: "A dependent value has been changed but the change has not been applied to the device."},
+	StatusBadDominantValueChanged:                 StatusCodeDesc{Name: "StatusBadDominantValueChanged", Text: "The related EngineeringUnit has been changed but this change has not been applied to the device. The Variable Value is still dependent on the previous unit but its status is currently Bad."},
+	StatusUncertainDependentValueChanged:          StatusCodeDesc{Name: "StatusUncertainDependentValueChanged", Text: "A dependent value has been changed but the change has not been applied to the device. The quality of the dominant variable is uncertain."},
+	StatusBadDependentValueChanged:                StatusCodeDesc{Name: "StatusBadDependentValueChanged", Text: "A dependent value has been changed but the change has not been applied to the device. The quality of the dominant variable is Bad."},
+	StatusGoodCommunicationEvent:                  StatusCodeDesc{Name: "StatusGoodCommunicationEvent", Text: "The communication layer has raised an event."},
+	StatusGoodShutdownEvent:                       StatusCodeDesc{Name: "StatusGoodShutdownEvent", Text: "The system is shutting down."},
+	StatusGoodCallAgain:                           StatusCodeDesc{Name: "StatusGoodCallAgain", Text: "The operation is not finished and needs to be called again."},
+	StatusGoodNonCriticalTimeout:                  StatusCodeDesc{Name: "StatusGoodNonCriticalTimeout", Text: "A non-critical timeout occurred."},
+	StatusBadInvalidArgument:                      StatusCodeDesc{Name: "StatusBadInvalidArgument", Text: "One or more arguments are invalid."},
+	StatusBadConnectionRejected:                   StatusCodeDesc{Name: "StatusBadConnectionRejected", Text: "Could not establish a network connection to remote server."},
+	StatusBadDisconnect:                           StatusCodeDesc{Name: "StatusBadDisconnect", Text: "The server has disconnected from the client."},
+	StatusBadConnectionClosed:                     StatusCodeDesc{Name: "StatusBadConnectionClosed", Text: "The network connection has been closed."},
+	StatusBadInvalidState:                         StatusCodeDesc{Name: "StatusBadInvalidState", Text: "The operation cannot be completed because the object is closed, uninitialized or in some other invalid state."},
+	StatusBadEndOfStream:                          StatusCodeDesc{Name: "StatusBadEndOfStream", Text: "Cannot move beyond end of the stream."},
+	StatusBadNoDataAvailable:                      StatusCodeDesc{Name: "StatusBadNoDataAvailable", Text: "No data is currently available for reading from a non-blocking stream."},
+	StatusBadWaitingForResponse:                   StatusCodeDesc{Name: "StatusBadWaitingForResponse", Text: "The asynchronous operation is waiting for a response."},
+	StatusBadOperationAbandoned:                   StatusCodeDesc{Name: "StatusBadOperationAbandoned", Text: "The asynchronous operation was abandoned by the caller."},
+	StatusBadExpectedStreamToBlock:                StatusCodeDesc{Name: "StatusBadExpectedStreamToBlock", Text: "The stream did not return all data requested (possibly because it is a non-blocking stream)."},
+	StatusBadWouldBlock:                           StatusCodeDesc{Name: "StatusBadWouldBlock", Text: "Non blocking behaviour is required and the operation would block."},
+	StatusBadSyntaxError:                          StatusCodeDesc{Name: "StatusBadSyntaxError", Text: "A value had an invalid syntax."},
+	StatusBadMaxConnectionsReached:                StatusCodeDesc{Name: "StatusBadMaxConnectionsReached", Text: "The operation could not be finished because all available connections are in use."},
+}
diff --git a/uasc/config.go b/uasc/config.go
index 7a0b65f..9ba9d8a 100644
--- a/uasc/config.go
+++ b/uasc/config.go
@@ -9,8 +9,9 @@ import (
 	"encoding/binary"
 	"time"
 
-	"github.com/gopcua/opcua/errors"
 	"github.com/gopcua/opcua/ua"
+
+	"github.com/pkg/errors"
 )
 
 // Config represents a configuration which UASC client/server has in common.
diff --git a/uasc/message.go b/uasc/message.go
index c6d36ba..0da4ed0 100644
--- a/uasc/message.go
+++ b/uasc/message.go
@@ -5,7 +5,8 @@
 package uasc
 
 import (
-	"github.com/gopcua/opcua/errors"
+	"fmt"
+
 	"github.com/gopcua/opcua/id"
 	"github.com/gopcua/opcua/ua"
 )
@@ -33,7 +34,7 @@ func (m *MessageHeader) Decode(b []byte) (int, error) {
 		buf.ReadStruct(m.SymmetricSecurityHeader)
 
 	default:
-		return buf.Pos(), errors.NewErrInvalidType(m, "decode", "should be one of OPN, MSG, CLO")
+		return buf.Pos(), fmt.Errorf("invalid message type %q", m.Header.MessageType)
 	}
 
 	m.SequenceHeader = new(SequenceHeader)
@@ -129,7 +130,7 @@ func (m *Message) Encode() ([]byte, error) {
 	case "CLO", "MSG":
 		body.WriteStruct(m.SymmetricSecurityHeader)
 	default:
-		return nil, errors.NewErrInvalidType(m, "serialize", "should be one of OPN, MSG, CLO")
+		return nil, fmt.Errorf("invalid message type %q", m.Header.MessageType)
 	}
 	body.WriteStruct(m.SequenceHeader)
 	body.WriteStruct(m.TypeID)
diff --git a/utils/endpoint.go b/utils/endpoint.go
index f52fc45..558b53e 100644
--- a/utils/endpoint.go
+++ b/utils/endpoint.go
@@ -8,8 +8,6 @@ import (
 	"fmt"
 	"net"
 	"strings"
-
-	"github.com/gopcua/opcua/errors"
 )
 
 // ResolveEndpoint returns network type, address, and error splitted from EndpointURL.
@@ -18,7 +16,7 @@ import (
 func ResolveEndpoint(endpoint string) (network string, addr *net.TCPAddr, err error) {
 	elems := strings.Split(endpoint, "/")
 	if elems[0] != "opc.tcp:" {
-		return "", nil, errors.NewErrUnsupported(elems[0], "should be in \"opc.tcp://<addr[:port]>/path/to/somewhere\" format.")
+		return "", nil, fmt.Errorf("invalid endpoint %s", endpoint)
 	}
 
 	addrString := elems[2]
@@ -30,7 +28,7 @@ func ResolveEndpoint(endpoint string) (network string, addr *net.TCPAddr, err er
 	addr, err = net.ResolveTCPAddr(network, addrString)
 	switch err.(type) {
 	case *net.DNSError:
-		return "", nil, errors.New("could not resolve address")
+		return "", nil, fmt.Errorf("could not resolve address %s", addrString)
 	}
 	return
 }


Test patch:
diff --git a/errors/errors_test.go b/errors/errors_test.go
deleted file mode 100644
index 1fcb9e6..0000000
--- a/errors/errors_test.go
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2018-2019 opcua authors. All rights reserved.
-// Use of this source code is governed by a MIT-style license that can be
-// found in the LICENSE file.
-
-// XXX - Implement!
-package errors
-
-import (
-	"testing"
-
-	"github.com/pascaldekloe/goe/verify"
-)
-
-var dummy string
-
-func TestNewErrors(t *testing.T) {
-	t.Run("ErrTooShortToDecode", func(t *testing.T) {
-		got := NewErrTooShortToDecode(dummy, "should be XXX.")
-		want := &ErrTooShortToDecode{
-			Type:    dummy,
-			Message: "should be XXX.",
-		}
-		verify.Values(t, "", got, want)
-	})
-	t.Run("ErrInvalidLength", func(t *testing.T) {
-		got := NewErrInvalidLength(dummy, "should be XXX.")
-		want := &ErrInvalidLength{
-			Type:    dummy,
-			Message: "should be XXX.",
-		}
-		verify.Values(t, "", got, want)
-	})
-	t.Run("ErrUnsupported", func(t *testing.T) {
-		got := NewErrUnsupported(dummy, "XXX is not supported yet.")
-		want := &ErrUnsupported{
-			Type:    dummy,
-			Message: "XXX is not supported yet.",
-		}
-		verify.Values(t, "", got, want)
-	})
-	t.Run("ErrInvalidType", func(t *testing.T) {
-		got := NewErrInvalidType(dummy, "decode", "something's wrong.")
-		want := &ErrInvalidType{
-			Type:    dummy,
-			Action:  "decode",
-			Message: "something's wrong.",
-		}
-		verify.Values(t, "", got, want)
-	})
-	t.Run("ErrReceiverNil", func(t *testing.T) {
-		got := NewErrReceiverNil(dummy)
-		want := &ErrReceiverNil{
-			Type: dummy,
-		}
-		verify.Values(t, "", got, want)
-	})
-}
-
-func TestError(t *testing.T) {
-	t.Run("ErrTooShortToDecode", func(t *testing.T) {
-		got := NewErrTooShortToDecode(dummy, "should be XXX.").Error()
-		want := "too short to decode as string: should be XXX."
-		verify.Values(t, "", got, want)
-	})
-	t.Run("ErrInvalidLength", func(t *testing.T) {
-		got := NewErrInvalidLength(dummy, "should be XXX.").Error()
-		want := "got invalid Length in string: should be XXX."
-		verify.Values(t, "", got, want)
-	})
-	t.Run("ErrUnsupported", func(t *testing.T) {
-		got := NewErrUnsupported(dummy, "XXX is not supported yet.").Error()
-		want := "unsupported string: XXX is not supported yet."
-		verify.Values(t, "", got, want)
-	})
-	t.Run("ErrInvalidType", func(t *testing.T) {
-		got := NewErrInvalidType(dummy, "decode", "something's wrong.").Error()
-		want := "cannot decode as string: something's wrong."
-		verify.Values(t, "", got, want)
-	})
-	t.Run("ErrReceiverNil", func(t *testing.T) {
-		got := NewErrReceiverNil(dummy).Error()
-		want := "Receiver string is nil."
-		verify.Values(t, "", got, want)
-	})
-}
diff --git a/ua/write_response_test.go b/ua/write_response_test.go
index 9ecb96d..f318668 100644
--- a/ua/write_response_test.go
+++ b/ua/write_response_test.go
@@ -7,8 +7,6 @@ package ua
 import (
 	"testing"
 	"time"
-
-	"github.com/gopcua/opcua/status"
 )
 
 func TestWriteResponse(t *testing.T) {
@@ -23,7 +21,7 @@ func TestWriteResponse(t *testing.T) {
 					StringTable:        []string{},
 					AdditionalHeader:   NewExtensionObject(nil),
 				},
-				Results: []StatusCode{0},
+				Results: []StatusCode{StatusOK},
 			},
 			Bytes: []byte{
 				// Timestamp
@@ -55,7 +53,7 @@ func TestWriteResponse(t *testing.T) {
 					StringTable:        []string{},
 					AdditionalHeader:   NewExtensionObject(nil),
 				},
-				Results: []StatusCode{0, status.BadUserAccessDenied},
+				Results: []StatusCode{StatusOK, StatusBadUserAccessDenied},
 			},
 			Bytes: []byte{
 				// Timestamp
diff --git a/utils/endpoint_test.go b/utils/endpoint_test.go
index 8ae3fcf..efce9d0 100644
--- a/utils/endpoint_test.go
+++ b/utils/endpoint_test.go
@@ -49,13 +49,13 @@ func TestResolveEndpoint(t *testing.T) {
 			"tcp://10.0.0.1:4840/foo/bar",
 			"",
 			nil,
-			"unsupported string: should be in \"opc.tcp://<addr[:port]>/path/to/somewhere\" format.",
+			"invalid endpoint tcp://10.0.0.1:4840/foo/bar",
 		},
 		{ // Invalid, bad formatted schema
 			"opc.tcp:/10.0.0.1:4840/foo/bar",
 			"",
 			nil,
-			"could not resolve address",
+			"could not resolve address foo:4840",
 		},
 	}