Save error in database Golang - go

I'm running http request in golang
resp, err := client.Do(req)
if err != nil {
return "", err
}
So, it returns error back to the main function, that attempts to store it in the database:
_, err = db.Exec("UPDATE test SET error = $1 WHERE id = $2", error, id)
I receive the following error: sql: converting Exec argument #1's type: unsupported type errors.errorString, a struct exit status 1
So, I understand, that error has a different type, but I can't find information on how to pass the value of the error to the string. Could someone direct me in a right way.

Use the function:
error.Error()
to get a string representation of the error.
Tip: avoid naming variables with existing type names. error is a type name and it's also your variable name, which might lead to confusion.

Related

Golang smart contract issue during invoking

Facing an issue in golang smart contract, while invoking chaincode create function i am getting an error of argument.
Whenever I'm going to send a string of array as an argument in Chain-code function. I'm getting an issue.
here I'm attaching my function implementation.
func (m *MdmChaincode) CreateSeqMrNum(ctx contractapi.TransactionContextInterface, args []string) error {
SeqId := args [0]
SrNo := args [1]
DocType := args [2]
mtrSeqNo := &SeqMrNum{SeqId, SrNo, DocType}
seqMrNumAsBytes, err := json.Marshal(mtrSeqNo)
if err != nil {
return fmt.Errorf("Unable to marshal the JSON.")
}
err = ctx.GetStub().PutState(SeqId, seqMrNumAsBytes)
if err != nil {
return fmt.Errorf("Cannot add to World State: %s", err.Error())
}
return nil
}
Error: endorsement failure during invoke. response: status:500 message: "Error managing parameter param0. Conversion error. Value 'M1001' not passed in expected format []string.
Facing an issue in golang smart contract, while invoking chaincode create function I am getting an error of argument.
Whenever I'm going to send a string of array as an argument in Chain-code function. I'm getting an issue.
here I'm attaching my function implementation.
It seems like your transaction function implementation is expecting the client to pass a single argument, which is a slice of strings. How well this is supported, I am not sure. If it is, I think the contract runtime will be expecting the client to format that single argument as a JSON array of strings.
It might be easier to accept each piece of information as a separate parameter:
func (m *MdmChaincode) CreateSeqMrNum(
ctx contractapi.TransactionContextInterface,
seqID string,
srNo string,
docType string
) error {
...
}
and then have your client submit a transaction with those three distinct arguments:
contract.Submit("CreateSeqMrNum", client.WithArguments(seqID, srNo, docType))
Alternatively, if you want the client to pass a JSON (or some other format) parameter containing all the required information, you could accept a single string parameter that you then explicitly deserialise within the smart contract.

List ClusterServiceVersions using K8S Go client

I'm trying to use the K8S Go client to list the ClusterServiceVersions.
It could be enough to have the raw response body.
I've tried this:
data, err := clientset.RESTClient().Get().Namespace(namespace).
Resource("ClusterServiceVersions").
DoRaw(context.TODO())
if err != nil {
panic(err.Error())
}
fmt.Printf("%v", string(data))
But it returns the following error:
panic: the server could not find the requested resource (get ClusterServiceVersions.meta.k8s.io)
How do I specify to use the operators.coreos.com group?
Looking at some existing code I've also tried to add
VersionedParams(&v1.ListOptions{}, scheme.ParameterCodec)
But it result in this other error:
panic: v1.ListOptions is not suitable for converting to "meta.k8s.io/v1" in scheme "pkg/runtime/scheme.go:100"
It is possible to do a raw request using the AbsPath() method.
path := fmt.Sprintf("/apis/operators.coreos.com/v1alpha1/namespaces/%s/clusterserviceversions", namespace)
data, err := clientset.RESTClient().Get().
AbsPath(path).
DoRaw(ctx)
Also notice that if you want to define clientset using the interface (kubernetes.Interface) instead of the concrete type (*kubernetes.Clientset) the method clientset.RESTClient() is not directly accessible, but you can use the following one:
clientset.Discovery().RESTClient()

ERR wrong number of arguments for 'zadd' command

I have found this Error:
ERR wrong number of arguments for 'zadd' command in golang.
This is my code:
defaultPriority:type String
mb.MessageID:type string
mb.EndpointID: type string
_, err = mbDal.redisClient.ZAdd(mb.EndpointID, redis.Z{Score: defaultPriority, Member: mb.MessageID})
if err != nil {
return fmt.Errorf("failed to add mailbox id %s in redis; error %v", mb.MessageID, err)
}
How can I fix this error message?
zadd is used in go-redis/redis, and is defined here
// Redis `ZADD key score member [score member ...]` command.
func (c cmdable) ZAdd(key string, members ...*Z) *IntCmd {
Double-check your go.mod dependencies list.
10 months ago, in go-redis v7 (instead of current v8), the signature for that function was:
func (c *cmdable) ZAdd(key string, members ...Z) *IntCmd {
It used Z instead of (today) *Z.
In your case, you should pass:
&redis.Z{Score: defaultPriority, Member: mb.MessageID}
I was trying to insert redis.Z{Score: [an int value], Member: code} to Redis sorted set and it failed with that error.
So I checked my logic and find out someone calling my method with code as an empty string. in my case first insert was successful but after that, all insert failed with that error.
I'm using github.com/go-redis/redis v6.15.6

What is good practice for nested function's return error? [duplicate]

I wondering what is the best way to handle error form multiple level abstraction in go. Every time if I must add a new level abstraction to program, I am forced to transfer error code from level less to level high. Thereby is duplicate communitaces in log file or I must remmember to delete communicate form level low and transfer him to level higher. Below simply example. I skipped creating each object to more shortly and celar code, but I think You understand my problem
type ObjectOne struct{
someValue int
}
func (o* ObjectOne)CheckValue()error{
if o.someValue == 0 {
SomeLogger.Printf("Value is 0 error program") // communicate form first level abstraction to logger
return errors.New("Internal value in object is 0")
}
return nil
}
type ObjectTwoHigherLevel struct{
objectOne ObjectOne
}
func (oT* ObjectTwoHigherLevel)CheckObjectOneIsReady() error{
if err := oT.objectOne.CheckValue() ; err != nil{
SomeLogger.Printf("Value in objectOne is not correct for objectTwo %s" , err) // second communicate
return err
}
return nil
}
type ObjectThreeHiggerLevel struct{
oT ObjectTwoHigherLevel
}
func (oTh* ObjectThreeHiggerLevel)CheckObjectTwoIsReady()error{
if err := oTh.oT.CheckObjectOneIsReady() ; err != nil{
SomeLogger.Printf("Value in objectTwo is not correct for objectThree %s" , err)
return err
}
return nil
}
In result in log file I get duplicate posts
Value is 0 error program
Value in objectOne is not correct for objectTwo Internal value in object is 0
Value in objectTwo is not correct for objectThree Internal value in object is 0
In turn if I only transfer some err to higher level without additional log I lost information what happend in each level.
How this solve ? How privent duplicate communicates ? Or My way is the good and the only ?
Problem is more frustrating if I create a few object which search something in database on a few abstraction level then I get also few lines form this same task in logFile.
EDIT: This answer pre-dates Go 1.13 which provides something similar to the presented technique. Please check The Go Blog: Working with Errors in Go 1.13.
You should either handle an error, or not handle it but delegate it to a higher level (to the caller). Handling the error and returning it is bad practice as if the caller also does the same, the error might get handled several times.
Handling an error means inspecting it and making a decision based on that, which may be you simply log it, but that also counts as "handling" it.
If you choose to not handle but delegate it to a higher level, that may be perfectly fine, but don't just return the error value you got, as it may be meaningless to the caller without context.
Annotating errors
A really nice and recommended way of delegation is Annotating errors. This means you create and return a new error value, but the old one is also wrapped in the returned value. The wrapper provides the context for the wrapped error.
There is a public library for annotating errors: github.com/pkg/errors; and its godoc: errors
It basically has 2 functions: 1 for wrapping an existing error:
func Wrap(cause error, message string) error
And one for extracting a wrapped error:
func Cause(err error) error
Using these, this is how your error handling may look like:
func (o *ObjectOne) CheckValue() error {
if o.someValue == 0 {
return errors.New("Object1 illegal state: value is 0")
}
return nil
}
And the second level:
func (oT *ObjectTwoHigherLevel) CheckObjectOneIsReady() error {
if err := oT.objectOne.CheckValue(); err != nil {
return errors.Wrap(err, "Object2 illegal state: Object1 is invalid")
}
return nil
}
And the third level: call only the 2nd level check:
func (oTh *ObjectThreeHiggerLevel) CheckObjectTwoIsReady() error {
if err := oTh.ObjectTwoHigherLevel.CheckObjectOneIsReady(); err != nil {
return errors.Wrap(err, "Object3 illegal state: Object2 is invalid")
}
return nil
}
Note that since the CheckXX() methods do not handle the errors, they don't log anything. They are delegating annotated errors.
If someone using ObjectThreeHiggerLevel decides to handle the error:
o3 := &ObjectThreeHiggerLevel{}
if err := o3.CheckObjectTwoIsReady(); err != nil {
fmt.Println(err)
}
The following nice output will be presented:
Object3 illegal state: Object2 is invalid: Object2 illegal state: Object1 is invalid: Object1 illegal state: value is 0
There is no pollution of multiple logs, and all the details and context are preserved because we used errors.Wrap() which produces an error value which formats to a string which preserves the wrapped errors, recursively: the error stack.
You can read more about this technique in blog post:
Dave Cheney: Don’t just check errors, handle them gracefully
"Extending" errors
If you like things simpler and / or you don't want to hassle with external libraries and you're fine with not being able to extract the original error (the exact error value, not the error string which you can), then you may simply extend the error with the context and return this new, extended error.
Extending an error is easiest done by using fmt.Errorf() which allows you to create a "nice" formatted error message, and it returns you a value of type error so you can directly return that.
Using fmt.Errorf(), this is how your error handling may look like:
func (o *ObjectOne) CheckValue() error {
if o.someValue == 0 {
return fmt.Errorf("Object1 illegal state: value is %d", o.someValue)
}
return nil
}
And the second level:
func (oT *ObjectTwoHigherLevel) CheckObjectOneIsReady() error {
if err := oT.objectOne.CheckValue(); err != nil {
return fmt.Errorf("Object2 illegal state: %v", err)
}
return nil
}
And the third level: call only the 2nd level check:
func (oTh *ObjectThreeHiggerLevel) CheckObjectTwoIsReady() error {
if err := oTh.ObjectTwoHigherLevel.CheckObjectOneIsReady(); err != nil {
return fmt.Errorf("Object3 illegal state: %v", err)
}
return nil
}
And the following error message would be presented at ObjectThreeHiggerLevel should it decide to "handle" it:
o3 := &ObjectThreeHiggerLevel{}
if err := o3.CheckObjectTwoIsReady(); err != nil {
fmt.Println(err)
}
The following nice output will be presented:
Object3 illegal state: Object2 illegal state: Object1 illegal state: value is 0
Be sure to also read blog post: Error handling and Go
There are various libraries that embed stack traces in Go errors. Simply create your error with one of those, and it will bubble up with the full stack context you can later inspect or log.
One such library:
https://github.com/go-errors/errors
And there are a few others I forgot.

Best practice to handle error from multiple abstract level

I wondering what is the best way to handle error form multiple level abstraction in go. Every time if I must add a new level abstraction to program, I am forced to transfer error code from level less to level high. Thereby is duplicate communitaces in log file or I must remmember to delete communicate form level low and transfer him to level higher. Below simply example. I skipped creating each object to more shortly and celar code, but I think You understand my problem
type ObjectOne struct{
someValue int
}
func (o* ObjectOne)CheckValue()error{
if o.someValue == 0 {
SomeLogger.Printf("Value is 0 error program") // communicate form first level abstraction to logger
return errors.New("Internal value in object is 0")
}
return nil
}
type ObjectTwoHigherLevel struct{
objectOne ObjectOne
}
func (oT* ObjectTwoHigherLevel)CheckObjectOneIsReady() error{
if err := oT.objectOne.CheckValue() ; err != nil{
SomeLogger.Printf("Value in objectOne is not correct for objectTwo %s" , err) // second communicate
return err
}
return nil
}
type ObjectThreeHiggerLevel struct{
oT ObjectTwoHigherLevel
}
func (oTh* ObjectThreeHiggerLevel)CheckObjectTwoIsReady()error{
if err := oTh.oT.CheckObjectOneIsReady() ; err != nil{
SomeLogger.Printf("Value in objectTwo is not correct for objectThree %s" , err)
return err
}
return nil
}
In result in log file I get duplicate posts
Value is 0 error program
Value in objectOne is not correct for objectTwo Internal value in object is 0
Value in objectTwo is not correct for objectThree Internal value in object is 0
In turn if I only transfer some err to higher level without additional log I lost information what happend in each level.
How this solve ? How privent duplicate communicates ? Or My way is the good and the only ?
Problem is more frustrating if I create a few object which search something in database on a few abstraction level then I get also few lines form this same task in logFile.
EDIT: This answer pre-dates Go 1.13 which provides something similar to the presented technique. Please check The Go Blog: Working with Errors in Go 1.13.
You should either handle an error, or not handle it but delegate it to a higher level (to the caller). Handling the error and returning it is bad practice as if the caller also does the same, the error might get handled several times.
Handling an error means inspecting it and making a decision based on that, which may be you simply log it, but that also counts as "handling" it.
If you choose to not handle but delegate it to a higher level, that may be perfectly fine, but don't just return the error value you got, as it may be meaningless to the caller without context.
Annotating errors
A really nice and recommended way of delegation is Annotating errors. This means you create and return a new error value, but the old one is also wrapped in the returned value. The wrapper provides the context for the wrapped error.
There is a public library for annotating errors: github.com/pkg/errors; and its godoc: errors
It basically has 2 functions: 1 for wrapping an existing error:
func Wrap(cause error, message string) error
And one for extracting a wrapped error:
func Cause(err error) error
Using these, this is how your error handling may look like:
func (o *ObjectOne) CheckValue() error {
if o.someValue == 0 {
return errors.New("Object1 illegal state: value is 0")
}
return nil
}
And the second level:
func (oT *ObjectTwoHigherLevel) CheckObjectOneIsReady() error {
if err := oT.objectOne.CheckValue(); err != nil {
return errors.Wrap(err, "Object2 illegal state: Object1 is invalid")
}
return nil
}
And the third level: call only the 2nd level check:
func (oTh *ObjectThreeHiggerLevel) CheckObjectTwoIsReady() error {
if err := oTh.ObjectTwoHigherLevel.CheckObjectOneIsReady(); err != nil {
return errors.Wrap(err, "Object3 illegal state: Object2 is invalid")
}
return nil
}
Note that since the CheckXX() methods do not handle the errors, they don't log anything. They are delegating annotated errors.
If someone using ObjectThreeHiggerLevel decides to handle the error:
o3 := &ObjectThreeHiggerLevel{}
if err := o3.CheckObjectTwoIsReady(); err != nil {
fmt.Println(err)
}
The following nice output will be presented:
Object3 illegal state: Object2 is invalid: Object2 illegal state: Object1 is invalid: Object1 illegal state: value is 0
There is no pollution of multiple logs, and all the details and context are preserved because we used errors.Wrap() which produces an error value which formats to a string which preserves the wrapped errors, recursively: the error stack.
You can read more about this technique in blog post:
Dave Cheney: Don’t just check errors, handle them gracefully
"Extending" errors
If you like things simpler and / or you don't want to hassle with external libraries and you're fine with not being able to extract the original error (the exact error value, not the error string which you can), then you may simply extend the error with the context and return this new, extended error.
Extending an error is easiest done by using fmt.Errorf() which allows you to create a "nice" formatted error message, and it returns you a value of type error so you can directly return that.
Using fmt.Errorf(), this is how your error handling may look like:
func (o *ObjectOne) CheckValue() error {
if o.someValue == 0 {
return fmt.Errorf("Object1 illegal state: value is %d", o.someValue)
}
return nil
}
And the second level:
func (oT *ObjectTwoHigherLevel) CheckObjectOneIsReady() error {
if err := oT.objectOne.CheckValue(); err != nil {
return fmt.Errorf("Object2 illegal state: %v", err)
}
return nil
}
And the third level: call only the 2nd level check:
func (oTh *ObjectThreeHiggerLevel) CheckObjectTwoIsReady() error {
if err := oTh.ObjectTwoHigherLevel.CheckObjectOneIsReady(); err != nil {
return fmt.Errorf("Object3 illegal state: %v", err)
}
return nil
}
And the following error message would be presented at ObjectThreeHiggerLevel should it decide to "handle" it:
o3 := &ObjectThreeHiggerLevel{}
if err := o3.CheckObjectTwoIsReady(); err != nil {
fmt.Println(err)
}
The following nice output will be presented:
Object3 illegal state: Object2 illegal state: Object1 illegal state: value is 0
Be sure to also read blog post: Error handling and Go
There are various libraries that embed stack traces in Go errors. Simply create your error with one of those, and it will bubble up with the full stack context you can later inspect or log.
One such library:
https://github.com/go-errors/errors
And there are a few others I forgot.

Resources