kt_errors

package
v2.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 21, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// This is pretty generic - any case something internally failed we want to mark it like that
	ERRCODE_INTERNAL_ERROR = "internal"

	// The config of the service is somehow wrong and this is causing a bad state
	ILLEGALSTATE_ERRCODE_CONFIG_ERROR = "config_error"
	// A dependency is permanently missing
	ILLEGALSTATE_ERRCODE_DEPENDENCY_MISSING = "missing_dependency"
	// Can be a temporary problem when e.g. we rely on an external system but somehow we can not reach it right now
	ILLEGALSTATE_ERRCODE_DEPENDENCY_UNAVAILABLE = "unavailable_dependency"
	// What we expected did not happen / we got something else
	ILLEGALSTATE_ERRCODE_EXCPECTATION_FAILED = "expectation_failed"
	// Something timed out - job is not done, state is not good
	ILLEGALSTATE_ERRCODE_TIMED_OUT = "timed_out"
	// Something has reached its limits - no more is possible
	ILLEGALSTATE_ERRCODE_EXHAUSTED = "exhausted"
	// We tried to serialize something into JSON/Yaml/binary etc but it failed. This often can indicate a problem with the original input.
	ILLEGALSTATE_ERRCODE_SERIALIZATION_FAILED = "serialization_failed"
	// We tried to deserialize something from JSON/Yaml/binary etc but it failed. This often can indicate a problem with the original input.
	ILLEGALSTATE_ERRCODE_DESERIALIZATION_FAILED = "deserialization_failed"
	// You can use this if you think this error only possible if we clearly have a bug in the code.
	// Time to time happens you find yourself in an error handling case you know "this is impossible" if I find myself here.
	ILLEGALSTATE_ERRCODE_CODE_BUG = "code_bug"

	// Use this error code if you expected something else as a type
	VALIDATION_ERRCODE_WRONG_DATATYPE = "wrong_datatype"
	// Use this error code if you expected a sepcific format for something but you received something else instead
	VALIDATION_ERRCODE_WRONG_FORMAT = "wrong_format"
	// Use this error code if you expected a mandatory parameter but was not provided
	VALIDATION_ERRCODE_MISSING_MANDATORY = "mandatoy_info_missing"
	// Use this error code if somewhere you expected to get nothing (e.g. a field should be None) but you got something
	VALIDATION_ERRCODE_SHOULD_NOT_BE_PROVIDED = "should_not_be_provided"
	// Use this error code if however data was provided it is not valid - content wise
	VALIDATION_ERRCODE_INVALID_VALUE = "invalid_value"
	// Use this error code if provided data is trying to change a value which actually is read-only
	VALIDATION_ERRCODE_READONLY_VALUE_CHANGED = "readonly_value_changed"

	// Use this error code if you have a resource conflicting PrimaryKey or ID
	CONSTRAINTVIOLATION_ERRCODE_ID_ALREADY_TAKEN = "id_already_taken"
	// A bit more generic representation of the fact: something already exists
	CONSTRAINTVIOLATION_ERRCODE_ALREADY_EXIST = "already_exists"
	// The object / resource / whatever we were expected being there is actually not there
	CONSTRAINTVIOLATION_ERRCODE_DOES_NOT_EXIST = "not_exists"
	// A generic description of the fact that the preconditions you were expected is not met
	CONSTRAINTVIOLATION_ERRCODE_PRECONDITION_FAILED = "precondition_failed"
	// Use this error code if you have a resource conflicting assumed vs real versions
	CONSTRAINTVIOLATION_ERRCODE_VERSION_CONFLICT = "resource_version_conflict"

	// Use this if you expected to have an authentication at certain point but it is not there
	AUTHENTICATION_ERRCODE_MISSING = "auth_data_missing"
	// Use this if you however authentication data is there but it is clearly invalid - e.g. password was empty
	AUTHENTICATION_ERRCODE_INVALID = "auth_data_invalid"
	// Use this if however auth info was there but it is using a method which you do not support
	AUTHENTICATION_ERRCODE_NOT_SUPPORTED = "auth_method_not_supported"
	// Might make sense in situations like JWT tokens - data is valid but token is expired
	AUTHENTICATION_ERRCODE_EXPIRED = "auth_data_expired"
	// Use this if however auth info was there auth process was not successful
	AUTHENTICATION_ERRCODE_FAILED = "authentication_failed"

	// The actor can not do this.
	AUTHORIZATION_NO_PERMISSION = "no_permission"
	// Use this if the authorization process was not successful for whatever reason. So this does not mean
	// the actor has no permission, it just failed this time.
	AUTHORIZATION_ERRCODE_FAILED = "authorization_failed"
)
View Source
const (
	// If set then the possible {var} variables are getting resolved from the labels in the messages before returned.
	// And in this case these {var} variables by default also removed from the labels as they became part of the message - unless
	// you pass `LeaveMessageVarsInLabels` option.
	ResolveMessages SerializationOption = 1
	// If `ResolveMessages` is used but you explicitly want to leave the {var} variables in the labels (removed by default as they) use this option.
	LeaveMessageVarsInLabels = 2

	// If set then the JSON is indented with line breaks and tabs so becomes more human readable
	PrettyPrint = 3
	// By default the serialization only happens if Fault is public - to prevent data leak non-public Faults simply returning blank form.
	// But if you set this option explicitly then this defense mechanism gets disabled.
	AllowNonPublicSerialization = 4
)
View Source
const (
	// Audience role - user - for audience facing message templates.
	MSGAUDIENCE_USER = "user"
)

Variables

This section is empty.

Functions

func GetFaultAsFullJSON

func GetFaultAsFullJSON(fault Fault, options ...SerializationOption) ([]byte, error)

Alias over the Fault's member function `fault.ToFullJSON()` - see description there! You can also use the member function if you prefer that style more in your code.

func GetFaultAsNaturalJSON

func GetFaultAsNaturalJSON(fault Fault, forAudience string, options ...SerializationOption) ([]byte, error)

Alias over the Fault's member function `fault.ToNaturalJSON()` - see description there! You can also use the member function if you prefer that style more in your code.

func GetGrpcStatusCodeForFault

func GetGrpcStatusCodeForFault(fault Fault) (grpcStatus codes.Code)

Returns the gRPC status code you should use in the error response for the given `Fault`.

IMPORTANT! In case the `Fault` is not public then it is always INTERNAL error - otherwise it is determined from the attributes and the kind of the Fault.

Note: there is an alias for this method as `fault.GetGrpcStatusCode()` - if you prefer that style more.

func GetHttpStatusCodeForFault

func GetHttpStatusCodeForFault(fault Fault) (httpStatus int)

Returns the HTTP status code you should use in the error response for the given `Fault`.

IMPORTANT! In case the `Fault` is not public then it is always 500 INTERNAL ERROR - otherwise it is determined from the attributes and the kind of the Fault.

Note: there is an alias for this method as `fault.GetHttpStatusCode()` - if you prefer that style more.

Types

type ConversionOption added in v2.0.1

type ConversionOption interface {
	// contains filtered or unexported methods
}

Can be used as possible option passed into the conversion. Please see methods `OptionXXX()` for supported options!

func OptionLogLabels

func OptionLogLabels(labels []kt_logging.Label) ConversionOption

You can pass in labels with this option which will decorate the log event.

But **please note:** if you passed in `transactionId` then it is always added to the log labels. So only for this you do not need to bother with it.

func OptionWhitelistedFaultKinds

func OptionWhitelistedFaultKinds(inheritErrorCodes bool, kinds ...FaultKind) ConversionOption

When conversion is made from non-public `Fault` then by default the kind of the converted `Fault` is always `RuntimeFault`. However it is often practical to allow a few specific kinds of the `Fault` to be inherited as kind into the public `Fault` during the conversion - instead of hiding those kinds entirely.

With this option you can specify a set of `FaultKind`s to safely inherit. In this case the `ERRCODE_INTERNAL_ERROR` is not added if the kind of the original Fault was whitelisted. (As the whitelist itself already suggests a special scenario.)

type Fault

type Fault interface {
	error
	fmt.Stringer

	// Returns the type of this error.
	GetKind() FaultKind
	// Returns the message template unresolved (so with possible variable placeholders in it as is)
	GetMessageTemplate() string
	// Returns the message - with resolved variable placeholders from labels.
	GetMessage() string
	// Returns the message template meant for the given audience unresolved (so with possible variable placeholders in it as is).
	// If there is no template for the requested audience, empty string is returned.
	GetMessageTemplateForAudience(forAudience string) string
	// Returns the message meant for the given audience - with resolved variable placeholders from labels.
	// If there is no template for the requested audience, empty string is returned.
	GetMessageForAudience(forAudience string) string
	// Returns map view of message templates by audiences.
	// **Note:** This always makes and returns a copy so use it accordingly!
	GetMessageTemplatesByAudience() map[string]string
	// Tells if this error is suitable to leave the private boundary or not (public = no implementation details leaking for sure).
	IsPublic() bool
	// We extend the error with the possibility of check if error is retryable.
	IsRetryable() bool
	// Returns all associated error codes.
	// **Note:** This always makes and returns a copy so use it accordingly! If possible use `HasErrorCode()` instead.
	GetErrorCodes() []string
	// Tells if this error is carrying ANY of the listed error codes or not.
	HasErrorCode(codes ...string) bool
	// Returns the Cause of this error - which is another (any) error.
	GetCause() error
	// Errors can carry a set of labels. This returns them all.
	// **Note:** This always makes and returns a copy so use it accordingly! If you can use `GetLabel()` method instead.
	GetLabels() map[string]any
	// Returns a specific label if Fault has it - or Nil if does not have it. You can also take and use the returned `found` flag.
	GetLabel(key string) (value any, found bool)
	// Error supports tracking the call chain. You can optionally use this (or not, up to you). But if you do, this method returns the content of this.
	// The `GetSource()` method returns where the error was born - you can set this with the builder `WithSource()` method. Then as the error bubbles
	// up, each hop can use the `AddCallerToCallStack()` method. This is how call stack is building up - what you can retrieve with this method.
	// The last element is the source - returned by `GetSource()`. Then the previous element is who called the source. And so on. The first element
	// is the point who started the whole call chain.
	GetCallStack() []string
	// Tells you where the error is originated from. We do it the easiest way: we can put this into a string :-) That's it.
	// See the error builder `WithSource()` method! If you invoke `GetCallStack()` method, this will be actually the deepest element on the stack.
	GetSource() string

	// You can add a caller to the call stack. You can do this when you capture an error like this because it is returned to you.
	// As you can see, if you want you can pass in multiple string elements. If you do so, they will be automatically concatenated
	// using "." separator. Why is it useful? Because you can do something like this: `AddCallerToCallStack("mypackage", "mymethod")` e.g.
	AddCallerToCallStack(caller ...string)
	// As the error bubbles upwards in higher layers it is often a requirement you want to add a bit more context to it. In classic error handling this
	// often ends in building mapping-functions and you raise a completely new error attaching the original one as Cause or similar tacticts. However
	// this leads to lots of boilerplate code and often results in mistakes especially if you have multiple layers in your code and each one is doing the same.
	//
	// So instead enforcing this strategy `Fault` offers a simpler way. You do not need to create a brand new error just to add your context info but you
	// can simply extend it in place and let the original prublom bubble upwards with all the details it already has! Basically, you simply extend the
	// information with those details you know in the higher level layer only.
	//
	// Using this method you can do this. You can prepend (prefix) to the messageTemplate of the error with a piece of string.
	// It is really a prefix - imagine a simple concatenation! So you need to include separators, white-spaces etc at the end of your prefix str!
	// If you send in empty str nothing will happen.
	AddContextToMessage(msgTemplatePrefix string)
	// Same as `AddContextToMessage()` (read its comment!) but with this one you can extend the audience facing messages with more context. If the audience you
	// refer to with `forAudience` does not exist it will be created. And maybe good to know that the `msgTemplatePrefix` value in this case will be trimmed on
	// the right side (not just whitespaces but also ':' and '-' characters) so no need to worry about strange white spaces.
	// If you send in empty str in any parameters nothing will happen.
	AddContextToAudienceMessage(forAudience string, msgTemplatePrefix string)
	// Please read the comment of `AddContextToMessage()` method! You get a better understanding on the motivation and problem then.
	// With this method - as the error bubbles upwards - highler level layers might want to extend it with their custom error codes. You can do it in one go by
	// adding multiple at once.
	AddErrorCodes(c ...string)
	// Please read the comment of `AddContextToMessage()` method! You get a better understanding on the motivation and problem then.
	// As the error bubbles upwards higher level layers might want to extend it with more labels - especially since we have `AddContextToMessage()` and
	// `AddContextToAudienceMessage()` which can introduce new {var}-s into the messages.
	AddLabel(key string, value any)
	// Please read the comment of `AddContextToMessage()` method! You get a better understanding on the motivation and problem then.
	// As the error bubbles upwards higher level layers might want to extend it with more labels - especially since we have `AddContextToMessage()` and
	// `AddContextToAudienceMessage()` which can introduce new {var}-s into the messages.
	AddLabels(labels map[string]any)

	// Returns the HTTP status code you should use in the response if you fail from this Fault.
	// Note: this is a wrapper around the utility function `GetHttpStatusCodeForFault()` - you can use that if you prefer that form instead.
	// IMPORTANT! In case the `Fault` is not public then it is always 500 INTERNAL ERROR - otherwise it is determined from the attributes and the kind of the
	// Fault.
	GetHttpStatusCode() int
	// Returns the gRPC status code you should use in the response if you fail from this Fault.
	// Note: this is a wrapper around the utility function `GetGrpcStatusCodeForFault()` - you can use that if you prefer that form instead.
	// IMPORTANT! In case the `Fault` is not public then it is always INTERNAL error - otherwise it is determined from the attributes and the kind of the Fault.
	GetGrpcStatusCode() codes.Code

	// Returns the natural (most human readable) JSON form of this Fault - can come handy if you build e.g. HTTP APIs and you need quickly return an error
	// response. Check the available `SerializationOption`s you can use optionally!
	// This method returns a JSON like:
	//
	//    {
	//       "kind": "<the Kind>",
	//       "message": "<the default MessageTemplate or given 'forAudience' template - raw or resolved>",
	//       "isRetryable": true/false,
	//       "errorCodes": ["the", "error", "codes"],
	//       "labels": {
	//           "key1": <value1>,
	//           "key2": <value2>,
	//           ...
	//        }
	//    }
	//
	// As you see really internal details like "cause" or "call stack" etc are absolutely not revealed.
	//
	// IMPORTANT! To prevent accidental data leak this serialization only renders public Faults! If the Fault is non-public you get back empty
	// values only - unless you explicitly use `AllowNonPublicSerialization` option!
	//
	// Parameters:
	// - `forAudience` - if you pass empty string you get back the default MessageTemplate - otherwise the specific audience message comes back
	ToNaturalJSON(forAudience string, options ...SerializationOption) ([]byte, error)

	// Just like `ToNaturalJSON()` this also returns a JSON representation but this one returns the "message" and "messagesByAudience"
	// separately - revealing more internal structure.
	//
	// However really internal details like "cause" or "call stack" etc are absolutely not revealed even in this form.
	//
	// IMPORTANT! To prevent accidental data leak this serialization only renders public Faults! If the Fault is non-public you get back empty
	// values only - unless you explicitly use `AllowNonPublicSerialization` option!
	ToFullJSON(options ...SerializationOption) ([]byte, error)
}

Our unified, data rich Keytiles-internal error which is able to carry many and all necessarry information and let it bubble up from literally any layers: even from libraries or simply service internal layers.

The most important concept: An error **can be classified as "public"** - yes or no. Public errors are suitable to leave the boundary and even show it to users - as they are phrased the way a) message is clear b) not leaking out internal implementation details for sure. If an error is non-Public then it is considered unsafe in the above sense and can be converted into a public version using method `NewPublicFaultFromAnyError()` - see method comments to get a better picture what is happening then!

An error like this is data rich - as we already wrote. It can

  • Carry error codes - for machine readability (strings - see predefined `*_ERRCODE_*` codes, but you can also define your own)
  • The error is typed - see `ErrorType`s! This also helps a lot in machine readability as well as properly convert then e.g. to Http/gRPC status codes!
  • Carry the cause - the error which caused this error
  • Carry labels (key-value pairs) associated with this error
  • The message is not just a dumb string but can be a template! It can contain variable placeholders (Python style - "My error message with {var1} and {var2}") which can be resolved from labels!
  • And apart from the default message it can also carry different message templates meant for different audiences

To construct an error with comfort we use builder pattern. You can use `NewFaultBuilder()` or `NewPublicFaultBuilder()` to quickly create a builder for a non-public or public error and fine tune the data it will carry.

Please note: this object is semi-immutable! Many things you can NOT change but some info you can extend, add to it (mutate) as error bubbles upwards the call chain. See `AddXXX()` methods!

IMPORTANT NOTE - for logging or printing into string: Use `VarPrinter` if you want the error printed using its `String()` method! Otherwise the `Error()` method will be used by Go by default as this is `error` type. The `Error()` is just returning / printing the message and optionally error codes, labels. Human readable form. Full info printed only by `String()` method which is probably what you want to log.

func IsFault

func IsFault(err error) (bool, Fault)

Tests the given error if this is a `Fault` or not. If yes then returns true and the converted Fault. If not then returns false and nil. If the provided error is nil, then it is NOT a Fault by default.

func NewPublicFaultFromAnyError

func NewPublicFaultFromAnyError(original error, transactionId string, loggerToUse *kt_logging.Logger, options ...ConversionOption) Fault

Turns any error into a public Fault instance.

In case the error is already isPublic=true `Fault` then it is returned as it is. Piece of cake :-)

In other cases - even if the error is a `Fault` but isPublic=false - the error is treated as unsafe. Details of the error can easily contain implementation details (e.g. we use S3 buckets which failed - the message can reveal this fact we use S3 buckets - not good)

Therefore what happens is that

  • The method will log the original error. (This is why we need a `loggerToUse` param - see below)
  • Then construct an isPublic=true `Fault` with generic safe message like "something has happened - details in the log".
  • Adds error code `ERRCODE_INTERNAL_ERROR`. (If you used `OptionWhitelistedFaultKinds()` that can fine grain this - see description!)
  • Sets the `cause` of the error to the original error.

In case the original error is isPublic=false `Fault` then we can keep some data from the original error for sure - but with care! Retry behavior is alwqys inherited. However the message of the error is still considered unsafe. But if it carries message for audience `MSGAUDIENCE_USER` then that one turns into the main message of the converted public error. All labels removed but the ones used in any `messageTemplatesByAudience`. And original error codes are also removed. They can potentially again leak out internal implementation details.

Arguments:

  • 'original': The error you want to turn into a public `Fault`.
  • 'transactionId': If you have a transaction ID pass it here! Then it will appear in the log as label, added to the Fault as "transactionId" label and also might appear in converted error message. Otherwise pass empty string simply.
  • 'loggerToUse': This logger is used to log the original fault so we have it, because the converted fault will very likely remove MANY specific details. In case no logger provided then a default Logger will be used for this.
  • 'options': You can pass in options to the conversion to fine grain how it behaves - please check `kt_errors.OptionXXX()` methods to see possibilities!

type FaultBuilder

type FaultBuilder struct {
	// contains filtered or unexported fields
}

func NewFaultBuilder

func NewFaultBuilder(errType FaultKind) *FaultBuilder

Creates a new FaultBuilder marked "non public" and you can convenient way fine tune the error before you invoke `Build()` method on it. You must specify the kind of the error right away - this is not changeable later.

func NewPublicFaultBuilder

func NewPublicFaultBuilder(errType FaultKind) *FaultBuilder

Creates a new FaultBuilder for "public" errors and you can convenient way fine tune the error before you invoke `Build()` method on it. You must specify the kind of the error right away - this is not changeable later.

func (*FaultBuilder) Build

func (builder *FaultBuilder) Build() Fault

func (*FaultBuilder) WithCause

func (builder *FaultBuilder) WithCause(e error) *FaultBuilder

You can attach the error which caused this error to this error.

func (*FaultBuilder) WithErrorCodes

func (builder *FaultBuilder) WithErrorCodes(c ...string) *FaultBuilder

You can add error codes to this error - multiple in one call. Error codes are simply strings. There are several predefined ones - see `*_ERRCODE_*` constants - but you can also define you owns of course.

func (*FaultBuilder) WithExactLabels

func (builder *FaultBuilder) WithExactLabels(labels map[string]any) *FaultBuilder

Sets the labels (key-value pairs) attached to this error to the given map - all previous labels will be removed.

func (*FaultBuilder) WithExactMessageTemplatesByAudience

func (builder *FaultBuilder) WithExactMessageTemplatesByAudience(templates map[string]string) *FaultBuilder

Adds all audience message templates to the error - and these will override the possibly existing ones.

func (*FaultBuilder) WithIsRetryable

func (builder *FaultBuilder) WithIsRetryable(flag bool) *FaultBuilder

Sets if this error is retryable or not.

Please note: certain error types are inheritedly not retryable, e.g. ValidationError or NotImplementedError. Invoking this method on any of those will simply have no effect.

func (*FaultBuilder) WithLabel

func (builder *FaultBuilder) WithLabel(key string, value any) *FaultBuilder

Attaching a label (key-value pair) to this error.

func (*FaultBuilder) WithLabels

func (builder *FaultBuilder) WithLabels(labels map[string]any) *FaultBuilder

You can attach multiple labels (key-value pairs) in one go if you wish with this method. Please note that these will be simply merged into the existing labels! See also `WithExactLabels()` method!

func (*FaultBuilder) WithMessageTemplate

func (builder *FaultBuilder) WithMessageTemplate(msg string) *FaultBuilder

Setting the message template of the error. Why is it a "template"? Because you can use variables in it (Python style), e.g. "My string with {var1} and {var2} variables.". Then add these as labels (see `WithLabel()` / `WithLabels()`).

func (*FaultBuilder) WithMessageTemplateForAudience

func (builder *FaultBuilder) WithMessageTemplateForAudience(forAudience string, msg string) *FaultBuilder

Sets a message template for a specific audience.

func (*FaultBuilder) WithMessageTemplatesByAudience

func (builder *FaultBuilder) WithMessageTemplatesByAudience(templates map[string]string) *FaultBuilder

Adds all audience message templates to the error - this is a merge.

func (*FaultBuilder) WithSource

func (builder *FaultBuilder) WithSource(src ...string) *FaultBuilder

You can attach info to the error regarding where is it coming from? We do not use stacktraces from runtime as that is expensive and overkill. Yet, it can be helpful to know from where the error originates from. We do it in the easiest way: you can put this into a string the way you want :-) That's it. As you can see, if you want you can pass in multiple string elements. If you do so, they will be automatically concatenated using "." separator.

func (*FaultBuilder) WithoutCause

func (builder *FaultBuilder) WithoutCause() *FaultBuilder

Removes the attached cause from the error - if there was attached any previously.

func (*FaultBuilder) WithoutErrorCodes

func (builder *FaultBuilder) WithoutErrorCodes(c ...string) *FaultBuilder

If you changed your mind you can remove specific error codes from the error.

func (*FaultBuilder) WithoutLabels

func (builder *FaultBuilder) WithoutLabels(keys ...string) *FaultBuilder

If you changed your mind you can remove specific labels (key-value pair) from this error.

func (*FaultBuilder) WithoutMessageTemplateForAudiences

func (builder *FaultBuilder) WithoutMessageTemplateForAudiences(forAudiences ...string) *FaultBuilder

If you changed your mind you can remove the template for this audience

type FaultKind

type FaultKind = string
const (
	// The most generic type without telling too much about the kind of the error - something bad has happened runtime.
	RuntimeFault FaultKind = "runtime"
	// Use this type if your code find itself in an unexpected state.
	// See the predefined `ILLEGALSTATE_ERRCODE_*` constants you can use as error codes to fine grain it further.
	IllegalStateFault FaultKind = "illegal_state"
	// Use this type if something is not implemented.
	NotImplementedFault FaultKind = "not_implemented"
	// You received an input/resource/data but that is not fully valid.
	// See the predefined `VALIDATION_ERRCODE_*` constants you can use as error codes to fine grain it further.
	ValidationFault FaultKind = "validation"
	// You (or user) assumed a certain state but it seems your assumption does not stand...
	// See the predefined `CONSTRAINTVIOLATION_ERRCODE_*` constants you can use as error codes to fine grain it further.
	ConstraintViolationFault FaultKind = "constraint_violation"
	// The resource which expected to be there is actually not. You can also model this with `ConstraintViolationError`
	// combined with `CONSTRAINTVIOLATION_ERRCODE_DOES_NOT_EXIST` error code thats kinda equivalent. But using this might
	// be simpler / more straightforward and this is pretty common problem often.
	ResourceNotFoundFault FaultKind = "resource_not_found"
	// Use this if there was a problem with authentication data.
	// See the predefined `AUTHENTICATION_ERRCODE_*` constants you can use as error codes to fine grain it further.
	AuthenticationFault FaultKind = "authentication"
	// The actor simply does not have permission or we could not determine if he/she/it has.
	// See the predefined `AUTHORIZATION_ERRCODE_*` constants you can use as error codes to fine grain it further.
	AuthorizationFault FaultKind = "authorization"
)

type SerializationOption

type SerializationOption int

Basically true/false options to change the serialization behavior

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL