So I have a basic function here
func (c *hotelController) Save(ctx *gin.Context) {
var hotel Hotel
ctx.ShouldBindJSON(&hotel)
if err:=db.Select("hotel_code","hotel_name","hotel_desc").Create(hotel);err!=nil{
ctx.AbortWithStatusJSON(http.StatusInternalServerError,gin.H{
"message":"Internal Server Error",
"error":err,
})
}
ctx.JSON(http.StatusOK, gin.H{
"message":"Save Hotel Data Success",
"data":hotel,
})
}
When I hit my API to this function I got these response always
json: unsupported type: func() time.Time
C:/Users/USER/go/pkg/mod/github.com/gin-gonic/gin#v1.7.7/render/json.go:56 (0x1015bc4)
JSON.Render: panic(err)
C:/Users/USER/go/pkg/mod/github.com/gin-gonic/gin#v1.7.7/context.go:927 (0x101cb06)
(*Context).Render: if err := r.Render(c.Writer); err != nil {
C:/Users/USER/go/pkg/mod/github.com/gin-gonic/gin#v1.7.7/context.go:970 (0x102e2a4)
(*Context).JSON: c.Render(code, render.JSON{Data: obj})
C:/Users/USER/go/pkg/mod/github.com/gin-gonic/gin#v1.7.7/context.go:199 (0x102e25e)
(*Context).AbortWithStatusJSON: c.JSON(code, jsonObj)
C:/xampp/htdocs/panorama_id_api_test/controllers/hotelController.go:51 (0x102e1b3)
(*hotelController).Save: ctx.AbortWithStatusJSON(http.StatusInternalServerError,gin.H{
C:/Users/USER/go/pkg/mod/github.com/gin-gonic/gin#v1.7.7/context.go:168 (0x1030a36)
(*Context).Next: c.handlersc.index
C:/Users/USER/go/pkg/mod/github.com/tpkeeper/gin-dump#v1.0.1/gindump.go:98 (0x102fdf4)
DumpWithOptions.func1: ctx.Next()
C:/Users/USER/go/pkg/mod/github.com/gin-gonic/gin#v1.7.7/context.go:168 (0x1024026)
(*Context).Next: c.handlersc.index
C:/Users/USER/go/pkg/mod/github.com/gin-gonic/gin#v1.7.7/logger.go:241 (0x1024009)
LoggerWithConfig.func1: c.Next()
C:/Users/USER/go/pkg/mod/github.com/gin-gonic/gin#v1.7.7/context.go:168 (0x1024dc1)
(*Context).Next: c.handlersc.index
C:/Users/USER/go/pkg/mod/github.com/gin-gonic/gin#v1.7.7/recovery.go:99 (0x1024dac)
CustomRecoveryWithWriter.func1: c.Next()
C:/Users/USER/go/pkg/mod/github.com/gin-gonic/gin#v1.7.7/context.go:168 (0x10235b0)
(*Context).Next: c.handlersc.index
C:/Users/USER/go/pkg/mod/github.com/gin-gonic/gin#v1.7.7/gin.go:555 (0x1023218)
(*Engine).handleHTTPRequest: c.Next()
C:/Users/USER/go/pkg/mod/github.com/gin-gonic/gin#v1.7.7/gin.go:511 (0x1022d51)
(*Engine).ServeHTTP: engine.handleHTTPRequest(c)
C:/Program Files/Go/src/net/http/server.go:2879 (0xeaa9ba)
serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
C:/Program Files/Go/src/net/http/server.go:1930 (0xea6067)
(*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
C:/Program Files/Go/src/runtime/asm_amd64.s:1581 (0xac4700)
goexit: BYTE $0x90 // NOP
Could someone help me? I just learned go 3 weeks ago.
Related
I hope you are well! First, I am new to the EIP world. I am trying to do a simple request reply with:
A Golang rabbitMQ client
An apache Camel route in Kotlin acting as a RabbitMQ server
I have tried to read all the docs I could and search for answers but I could't find nothing. I am basically desperate. Mainly I saw this and nothing has worked yet.
My goal is to do a sync request-reply as the image.
My Golang client looks like this:
func (r *RabbitMQConn) GetQueue(name string) *amqp.Queue {
ch := r.GetChannel()
defer ch.Close()
q, err := ch.QueueDeclare(
name,
false,
false,
true,
false,
nil,
)
if err != nil {
panic(err)
}
return &q
}
func (r *RabbitMQConn) PublishAndWait(routingKey string, correlationId string, event domain.SyncEventExtSend) (domain.SyncEventExtReceive, error) {
message, err := json.Marshal(event)
if err != nil {
return domain.SyncEventExtReceive{}, apperrors.ErrInternal
}
ch := r.GetChannel()
defer ch.Close()
q := r.GetQueue("response")
h, err := ch.Consume(
q.Name,
"",
true,
false,
false,
false,
nil,
)
if err != nil {
return domain.SyncEventExtReceive{}, err
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
err = ch.PublishWithContext(
ctx,
"",
routingKey,
false,
false,
amqp.Publishing{
ContentType: "application/json",
Body: message,
CorrelationId: correlationId,
ReplyTo: q.Name,
},
)
if err != nil {
return domain.SyncEventExtReceive{}, err
}
for d := range h {
fmt.Println("Received a message:", string(d.Body))
if d.CorrelationId == correlationId {
var event domain.SyncEventExtReceive
err = json.Unmarshal(d.Body, &event)
return event, err
}
}
return domain.SyncEventExtReceive{}, apperrors.ErrInternal
}
Basically, just consuming from the default exchange with a named response queue. Also, I send the queue name as the ReplyTo parameter and I give it a correlation id. The routing-key that is sent is daily-weather in this case.
On the server side, I tried to do the server with the default exchange, but Apache Camel forbids me to do nothing with that exchange.
from("rabbitmq:?queue=daily-weather&autoAck=true&autoDelete=false")
So, I assigned it the amq.direct exchange. However, that didn't also worked.
"rabbitmq:amq.direct?queue=daily-weather&autoAck=true&autoDelete=false"
Then, I added a second RabbitMQ endpoint to see if it would sent it, but nothing.
from("rabbitmq:amq.direct?queue=daily-weather&autoAck=true&autoDelete=false")
.log(LoggingLevel.INFO, "weather-daily", "Received message: \${body}")
.to("rabbitmq:amq.direct?queue=response&autoAck=true&autoDelete=false")
I ask if anybody has any simple example to do this with Apache Camel, because I am ultra lost. Any further detail can be shared if you contact me.
Thank you very much!!!! :)
SOLVED
Hi! After some time I decided to take a look to the spring-rabbitmq Camel component. I realised that Camel has exchange patterns, and rabbitmq, by default, sets it to inOut. This way, automatically returns the information back to the replyTo property.
val RABBIMQ_ROUTE =
"spring-rabbitmq:default?queues={{rabbitmq.weather.daily.routing_key}}"
default refers to the default exchange queue.
I have written a controller GetUser to get a particular user from Database(Firestore) on the basis of id I put in the query. If the user is not present in the database then it should give the message that "User not found". But along with this message I am getting nil keyword also in response.
The response I am getting:
{
"message": "User not found"
}null
When I hover on dsnap.Data() I get the information that
(firestore.DocumentSnapshot).Data on pkg.go.dev
Data returns the DocumentSnapshot's fields as a map. It is equivalent to
var m map[string]interface{}
d.DataTo(&m)
except that it returns nil if the document does not exist.
Controller:
func GetUser(c *gin.Context) {
paramID := c.Params.ByName("id")
........
........
........
dsnap, err := client.Collection("users").Doc(paramID).Get(ctx)
if err != nil {
fmt.Print(err)
c.IndentedJSON(http.StatusNotFound, gin.H{
"message": "User not found",
})
}
m := dsnap.Data()
c.IndentedJSON(http.StatusNotFound, gin.H(m))
}
Firestore reference link: https://pkg.go.dev/cloud.google.com/go/firestore#v1.6.1#DocumentSnapshot.Data
Can you guys please tell me how can I remove nil from the response?
Thank you.
This problem is solved now. I write "return" after the User not found response.
I have the code to download two files from Server and store It to In local using URLSession (let dataTask = defaultSession.downloadTask(with: url)). Everything Is working fine only the problem is it's downloading first file it's giving me success but the second file is not downloading completely.. So, I hope there is a way to restart download for the second file that gives error ..
I think there is way of doing that and start looking into it and I found this delegate method .. but not much help .. can anyone please help me out how to restart download if it fails .. Do i have to use handleEventsForBackgroundURLSession to clear up previous downloads..?
// bellow download method will triggered when i get filenames I am passing it to this and path is optional here..
func download(path: String?, filenames: [String]) -> Int {
for filename in filenames {
var downloadFrom = "ftp://" + username! + ":"
downloadFrom += password!.addingPercentEncoding(withAllowedCharacters: .urlPasswordAllowed)! + "#" + address!
if let downloadPort = port {
downloadFrom += ":" + String(downloadPort) + "/"
} else {
downloadFrom += "/"
}
if let downloadPath = path {
if !downloadPath.isEmpty {
downloadFrom += downloadPath + "/"
}
}
downloadFrom += filename
if let url = URL(string: downloadFrom) {
let dataTask = defaultSession.downloadTask(with: url)
dataTask.resume()
}
}
return DLResponseCode.success
}
Please find delegate methods bellow ..
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
var responseCode = DLResponseCode.success
// Move the file to a new URL
let fileManager = FileManager.default
let filename = downloadTask.originalRequest?.url?.lastPathComponent
let destUrl = cacheURL.appendingPathComponent(filename!)
do {
let data = try Data(contentsOf: location)
// Delete it if it exists first
if fileManager.fileExists(atPath: destUrl.path) {
do{
try fileManager.removeItem(at: destUrl)
} catch let error {
danLogError("Clearing failed downloadFOTA file failed: \(error)")
responseCode = DLResponseCode.datalogger.failToCreateRequestedProtocolPipe
}
}
try data.write(to: destUrl)
} catch {
danLogError("Issue saving data locally")
responseCode = DLResponseCode.datalogger.noDataConnection
}
// Complete the download message
let message = DLBLEDataloggerChannel.Commands.download(responseCode: responseCode).description
connectionManagerDelegate?.sendMessageToDatalogger(msg: message)
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if error == nil {
print("session \(session) download completed")
} else {
print("session \(session) download failed with error \(String(describing: error?.localizedDescription))")
// session.downloadTask(withResumeData: <#T##Data#>)
}
guard error != nil else {
return
}
danLogError("Session \(session) invalid with error \(String(describing: error))\n")
let responseCode = DLResponseCode.datalogger.failToCreateRequestedProtocolPipe
let message = DLBLEDataloggerChannel.Commands.download(responseCode: responseCode).description
connectionManagerDelegate?.sendMessageToDatalogger(msg: message)
}
// When I call didWriteData delegate method it's printing below data seems not dowloaded complete data ..
session <__NSURLSessionLocal: 0x103e37970> download task <__NSCFLocalDownloadTask: 0x108d2ee60>{ taskIdentifier: 2 } { running } wrote an additional 30028 bytes (total 988980 bytes) out of an expected 988980 bytes.
//error that I am getting for second file .. this error is coming some times not always but most of the times..
session <__NSURLSessionLocal: 0x103e37970> download failed with error Optional("cancelled")
Please help me out to figure it out .. If there is any way to handle download again after it fails or why it fails ..
The resume data, if the request is resumable, should be in the NSError object's userInfo dictionary.
Unfortunately, Apple seems to have completely trashed the programming guide for NSURLSession (or at least I can't find it in Google search results), and the replacement content in the reference is missing all of the sections that talk about how to do proper error handling (even the constant that you're looking for is missing), so I'm going to have to describe it all from memory with the help of looking at the headers. Ick.
The key you're looking for is NSURLSessionDownloadTaskResumeData.
If that key is present, its value is a small NSData blob. Store that, then use the Reachability API (with the actual hostname from that request's URL) to decide when to retry the request.
After Reachability tells you that the server is reachable, create a new download task with the resume data and start it.
I am trying to upload an Image to my s3 account using Golang and the amazon s3 api . I can get the imagine uploaded if I hard code the direct path such as
file, err := os.Open("/Users/JohnSmith/Documents/pictures/cars.jpg")
defer file.Close()
if err != nil {
fmt.Printf("err opening file: %s", err)
}
if I hard code the file path like that then the picture will be uploaded to my s3 account . However that approach is not good as I can't obviously hard code the direct image path to every image that I want to upload . My question is how can I upload images without having to Hardcode the path . This will be apart of an API where users will upload images so I clearly can not have a hard coded path . This is my code first the HTML
<form method="post" enctype="multipart/form-data" action="profile_image">
<h2>Image Upload</h2>
<p><input type="file" name="file" id="file"/> </p>
<p> <input type="submit" value="Upload Image"></p>
</form>
then this is my HTTP Post function method
func UploadProfile(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
var resultt string
resultt = "Hi"
sess, _ := session.NewSession(&aws.Config{
Region: aws.String("us-west-2"),
Credentials: credentials.NewStaticCredentials(aws_access_key_id,aws_secret_access_key, ""),
})
svc := s3.New(sess)
file, err := os.Open("Users/JohnSmith/Documents/pictures/cars.jpg")
defer file.Close()
if err != nil {
fmt.Printf("err opening file: %s", err)
}
fileInfo, _ := file.Stat()
size := fileInfo.Size()
buffer := make([]byte, size) // read file content to buffer
file.Read(buffer)
fileBytes := bytes.NewReader(buffer)
fileType := http.DetectContentType(buffer)
path := file.Name()
params := &s3.PutObjectInput{
Bucket: aws.String("my-bucket"),
Key: aws.String(path),
Body: fileBytes,
ContentLength: aws.Int64(size),
ContentType: aws.String(fileType),
}
resp, err := svc.PutObject(params)
if err != nil {
fmt.Printf("bad response: %s", err)
}
fmt.Printf("response %s", awsutil.StringValue(resp))
}
That is my full code above however when I try to do something such as
file, err := os.Open("file")
defer file.Close()
if err != nil {
fmt.Printf("err opening file: %s", err)
}
I get the following error
http: panic serving [::1]:55454: runtime error: invalid memory address or nil pointer dereference
goroutine 7 [running]:
err opening file: open file: no such file or directorynet/http.(*conn).serve.func1(0xc420076e80)
I can't use absolute path (filepath.Abs()) because some of the files will be outside of the GoPath and as stated other users will be uploading. Is there anyway that I can get a relative path ..
After POST to your API, images are temporarily saved in a OS's temp directory (different for different OS's) by default. To get this directory you can use, for example:
func GetTempLoc(filename string) string {
return strings.TrimRight(os.TempDir(), "/") + "/" + filename
}
Where:
filename is a header.Filename, i.e. file name received in your POST request. In Gin-Gonic framework you get it in your request handler as:
file, header, err := c.Request.FormFile("file")
if err != nil {
return out, err
}
defer file.Close()
Example: https://github.com/gin-gonic/gin#another-example-upload-file.
I'm sure in your framework there will be an analogue.
os.TempDir() is a function go give you a temp folder (details: https://golang.org/pkg/os/#TempDir).
TrimRight is used to ensure result of os.TempDir is consistent on different OSs
And then you use it as
file, err := os.Open(GetTempLoc(fileName))
...
I'm trying to connect to a remote Sql Anywhere 12.01 database with the following code:
let sqlanywhere = require('sqlanywhere');
let conn = sqlanywhere.createConnection();
let conn_params = {
Server : 'server:port',
UserId : 'user',
Password : 'pass'
};
conn.connect(conn_params, function() {
console.log("Connected!");
conn.exec('select * from cases', function (err, result) {
if (err) {
console.log(err);
} else {
console.log(result);
}
});
});
My console.log("Connected!") fires so I'm assuming that I've connected to the remote database? However, any query that I make results in this:
[Error: Code: -2001 Msg: Invalid Object]
I looked through the error codes online and didn't find this one. Anyone know why I may be experiencing it and how I can fix it?
The callback function should take two parameters: err and result. If err is undefined, then the connection succeeded, otherwise it indicates what error occurred. (In the case of connection, result will always be undefined.) Your code should look like this:
...
conn.connect( conn_params, function( err, result ) {
if( err ) {
console.log( "Connection failed: "+err );
} else {
console.log( "Connected!" );
}
...
});
I had to change "let" to "var" to make the javascript run. Also, your Server connection parameter should be the server name, not the location. You should change "Server" to "Host" to indicate the hostname / port.
Note: This answer was copied from the same question posted on sqlanywhere-forum.sap.com.