I am using
"google.golang.org/appengine/aetest"
package and setup my TestMain like this:
var myAeInst aetest.Instance
func TestMain(m *testing.M) {
var err error
myAeInst, err = aetest.NewInstance(&aetest.Options{StronglyConsistentDatastore: true})
defer tearDown()
c := m.Run()
os.Exit(code)
}
func tearDown() {
if myAeInst != nil {
myAeInst.Close()
}
}
But it stuck at aetest.NewInstance, any one encounter similar issue?
You're calling defer tearDown() and then os.Exit(code), which calls tearDown after os.Exit (i.e., never). You need to either explicitly call tearDown before os.Exit, or make a new function that you defer from that doesn't call os.Exit.
Related
I am not sure to understand the try / catch in solidity. The following code in intentionally wrong and the error should be caught, right?
function GetTest() external view returns (string memory) {
address _token_addr = 0x0000000000000000000000000000000000000000;
console.log("here");
ERC721 candidateContract = ERC721(_token_addr);
try candidateContract.supportsInterface(0x80ac58cd) {
console.log("try");
}
catch
{
console.log("catch");
}
return "";
}
What is the way to catch an error and check if the address has the expected type (token, address, contract) ?
The try/catch statement allows you to react on failed external calls
and contract creation calls
When you call candidateContract.supportsInterface(0x80ac58cd) if this function reverts, you will catch the error. For example, if you deploy those testCatch and ERC165 contracts
contract testCatch{
function GetTest() public view returns (string memory) {
// this is the address of deployed ERC165 contract down below
address _token_addr = 0x406AB5033423Dcb6391Ac9eEEad73294FA82Cfbc;
ERC165 candidateContract = ERC165(_token_addr);
try candidateContract.supportsInterface(0x80ac58cd) {
return "tried";
}
catch
{
return "catch";
}
}
}
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
// this contract originally was abstract but I removed it to be able to deploy
contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
// this require will fail
require(2==3,"wrong calculation");
return interfaceId == type(IERC165).interfaceId;
}
}
when you call the GetTest() function, it will revert because of require(2==3,"wrong calculation") line
However, if you removed the require line from ERC165 contract,
contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
And if you change this bytes4 "0x80ac58cd" to a wrong bytes4 "0x80ac5ccc", if you call the function, catch will not CATCH it. because supportsInterface function will not revert anything. So the code inside try block will run
WebSocket connection to 'ws://localhost:8080/websocket' failed: Error during WebSocket handshake: Unexpected response code: 404, this happens when I try to connect websocket from ReactJS to Backend(Go) where I have created a handler, this is my backend code router file
import (
"net/http"
"../server"
"github.com/gorilla/mux"
)
// Router is exported and used in main.go
func Router() *mux.Router {
router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/ws", server.HandleConnections) //
router.HandleFunc("/api/block", server.GetAllBlock).Methods("GET", "OPTIONS")
router.HandleFunc("/api/block", server.CreateBlock).Methods("POST", "OPTIONS")
router.PathPrefix("/").Handler(http.FileServer(http.Dir("../public")))
return router
}
This is my main
func runWebServer() {
r := router.Router()
fmt.Println("Starting server on the port 8080...")
log.Fatal(http.ListenAndServe("localhost:8080", r))
}
func main() {
go runWebServer()
}
This is my handleConnection function
func HandleConnections(w http.ResponseWriter, r *http.Request) {
fmt.Println("In handle")
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Fatal(err)
fmt.Println("Error in ebss")
}
fmt.Println("No error")
// make sure we close the connection when the function returns
// defer ws.Close()
// register our new client
nodes[ws] = true
for {
// Read in a new message as JSON and map it to a Message object
var course Course
err := ws.ReadJSON(&course)
if err != nil {
log.Printf("error: %v", err)
// delete(nodes, ws)
break
}
// Send the newly received message to the broadcast channel
broadcast <- course
}
}
This is my frontend React file where the 404 handshake error occurs
let endpoint = "http://localhost:8080";
class Blockchain extends Component {
componentDidMount() {
let ws = new WebSocket('ws://localhost:8080');//Here
console.log("webs",ws)
}
This is the error shown in browser when loading the page
Here is your primary issue:
func main() {
go runWebServer()
}
This runs the runWebServer function in a separate goroutine, which makes the main goroutine, the main() function call, continue past that line. Since there are no more instructions in your main function, the program returns. When a Go program returns, all child goroutines return. This program can't be relied upon to do anything because the main goroutine returns too quickly.
You should run the function in a blocking way like below or take a look at managing multiple goroutines. This guide may be a good place to start.
func main() {
runWebServer()
}
Using Api key I was able to fetch the videos in a playlist from Api Explorer. Execute without OAuth fetched the results json. Here is the link.
https://developers.google.com/apis-explorer/?hl=en_US#p/youtube/v3/youtube.playlistItems.list?part=snippet&playlistId=PLHyTuYqPkZCzt7mWZ4hmmrRdjLJiw6O2T&_h=2&
Implementing the same call using Go on App engine fails with below error:
Get https://www.googleapis.com/youtube/v3/playlistItems?alt=json&part=snippet&playlistId=PLHyTuYqPkZCzt7mWZ4hmmrRdjLJiw6O2T: http.DefaultTransport and http.DefaultClient are not available in App Engine. See https://cloud.google.com/appengine/docs/go/urlfetch/
Here is the code I use:
import (
"net/http"
"code.google.com/p/google-api-go-client/googleapi/transport"
"code.google.com/p/google-api-go-client/youtube/v3"
"log"
)
var service *youtube.Service
func init() {
var err error
log.Println("Apikey = ", apiKey)
client := &http.Client{Transport: &transport.APIKey{Key: apiKey}}
service, err = youtube.New(client)
if err != nil {
log.Println("ERROR in creating youtube New client ", err)
}
var items *youtube.PlaylistItemListResponse
if items, err = service.PlaylistItems.List("snippet").PlaylistId("PLHyTuYqPkZCzt7mWZ4hmmrRdjLJiw6O2T").Do(); err != nil {
log.Println("Error in fetching playlist items ", err) //this line shows the error
}
log.Println(Jsonify(items))
}
As of now, I run my code on local dev server i.e goapp serve
What is missing? How do I fetch youtube playlist videos using v3 api and ApiKey?
Unfortunately, the linked doc doesn't quite explain why your code isn't working. On App Engine, you need to use a special http.Transport provided by the urlfetch package; see https://cloud.google.com/appengine/docs/go/urlfetch/
Found the solution. Below code did the task for me.
func FetchVideos(w http.ResponseWriter, r *http.Request) {
var service *youtube.Service
ctx := appengine.NewContext(r)
transport := &transport.APIKey{
Key: apiKey,
Transport: &urlfetch.Transport{Context: ctx}}
client := &http.Client{Transport: transport}
var err error
service, err = youtube.New(client)
if err != nil {
log.Println("ERROR in creating youtube New client ", err)
}
var items *youtube.PlaylistItemListResponse
if items, err = service.PlaylistItems.List("snippet").PlaylistId("PLHyTuYqPkZCzt7mWZ4hmmrRdjLJiw6O2T").Do(); err != nil {
log.Println("Error in fetching playlist items ", err)
}
log.Println(Jsonify(items))
I'm going to try to explain this as best as I can.
I am using Parse.com and returning data from a Parse database class. I want to put this parse.com call in its own function in a custom class. The problem I am having is the completion. Where does it go? I've tried many different versions of adding it to my function but it isn't working.
Here is the function that takes the class name, table name, and sort descriptor and returns an array:
func queryDataInBackgroundWithBlock(parseClass:String, parseObject:String, sortDescriptor:NSSortDescriptor) -> [Any]
When I add the completion to it I use (which may not be correct):
func queryDataInBackgroundWithBlock(parseClass:String, parseObject:String, sortDescriptor:NSSortDescriptor, completion: (result: Any)->Void)
Now inside the function I use the Parse.com code to go out and get the data
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]!, error: NSError!) -> Void in
if error == nil {
// Do something with the found objects
for object in objects {
self.arrayOfObjects.append(object[parseObject]!)
}
} else {
// Log details of the failure
println("Error: \(error) \(error.userInfo!)")
}
}
My goal here is to send parameters to my class function, get the data from parse.com and then return the data as an Array AFTER the async call
I am trying to call it like this:
myClass.queryDataInBackgroundWithBlock("databaseName", parseObject: "columnName", sortDescriptor: orderBy){
(result: Any) in
println(result)
}
It's almost like it is a nested completion. How do I return the array after it is completed? Is it handed off to the function which then returns it, or does it need to return in the nested code, or what? It retrieves the data but the problem is the return AFTER completion.
UPDATE:
As I stated in the comment below:
query.findObjectsInBackgroundWithBlock({
(objects: [AnyObject]!, error: NSError!) -> Void in
if error == nil {
// Do something with the found objects
for object in objects {
self.arrayOfObjects.append(object[parseObject]!)
}
} else {
// Log details of the failure
println("Error: \(error) \(error.userInfo!)")
}
}, completion: {
//do something here
})
This is returning the error: "Extra argument completion in call"
I'm not sure how to add the completion at the end of the block so I added () around the block and inserted the completion. This is obviously wrong but I'm not sure how to add the completion at the end of the block as matt has suggested
UPDATE 2:
func queryDataInBackgroundWithBlock(parseClass:String, parseObject:String, sortDescriptor:NSSortDescriptor) -> [Any]{
var query = PFQuery(className:parseClass)
if sortDescriptor.key != "" {
query.orderBySortDescriptor(sortDescriptor)
}
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]!, error: NSError!) -> Void in
if error == nil {
// Do something with the found objects
for object in objects {
self.arrayOfObjects.append(object[parseObject]!!)
}
} else {
// Log details of the failure
println("Error: \(error) \(error.userInfo!)")
}
}
return self.arrayOfObjects //<-- needs to move to completion
}
Inside the function queryDataInBackgroundWithBlock you receive the completion block under the name completion. It takes one parameter. So the last thing you do, after you have the data, is call it, handing it the data:
completion(result:myData)
And since query.findObjectsInBackgroundWithBlock is itself async, you will need to make that call as the last thing inside the block of query.findObjectsInBackgroundWithBlock.
Like this:
func queryDataInBackgroundWithBlock(
parseClass:String, parseObject:String, sortDescriptor:NSSortDescriptor,
completion: (result: Any)->Void)
{
var query = PFQuery(className:parseClass)
if sortDescriptor.key != "" {
query.orderBySortDescriptor(sortDescriptor)
}
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]!, error: NSError!) -> Void in
if error == nil {
// Do something with the found objects
for object in objects {
self.arrayOfObjects.append(object[parseObject]!!)
}
} else {
// Log details of the failure
println("Error: \(error) \(error.userInfo!)")
}
completion(result:self.arrayOfObjects)
}
}
Suppose I have the following init function routing requests.
func init() {
http.HandleFunc("/user", handler1)
http.HandleFunc("/user/profile", handler2)
http.HandleFunc("/user/post", handler3)
....
....
}
All of these require that I have the user's profile.
I know I can
func handler1(w http.ResponseWriter, r *http.Request) {
getUserdata()
//Actual handler code
...
...
}
But, is there a way I can get the data without putting the function call in every handler? Is this even something Go would want you to do in the first place?
You have two options.
You can inplement the http.Handler interface
You Wrap all your http.HandlerFunc with a wrapper HandleFunc.
Since it looks like you want something simple I'll illustrate the WRapper
func Prehook(f http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
getUserData()
f(w, r)
}
}
func init() {
// use getUserData() call before your handler
http.HandleFunc("/user", Prehook(handler1))
// Don't use getUserData call before your handler
http.HandleFunc("/user/profile", handler2)
}