Render a template upon failed POST request [golang] - go

I want to handle the errors of a POST request and re-render the form with the errors displayed above it, but the only solution to handling errors I see is http.Error() but this returns a plaintext response, not an HTML page. Is there a way to executeTemplate() and re-render the html page with the form? Am I supposed to redirect the user to the same page? If so, how do I pass the error information to that redirected page?
Edit: So, when I use this code, and try to executeTemplate, the Post request returns a 200 status code (which is wrong) and it re-renders blank page, not the template I specified.
func PostSignup(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if r.Method != http.MethodPost {
http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed)
return
}
usr := users.User{}
usr.Username = r.FormValue("username")
usr.Email = r.FormValue("email")
usr.Hash = r.FormValue("password")
errors := CredErrors{}
errors.Error = "Username cannot be blank"
if usr.Username == "" {
// http.Error(w, "Username cannot be blank.", 400)
tpl.ExecuteTemplate(w, "signup.gothml", errors)
return
}

The answer is in the question:
Is there a way to executeTemplate() and re-render the html page with the form?
Yes, use executeTemplate to re-render the form. http.Error() is for returning HTTP errors, not form validation errors. If the form fails validation and you want to redisplay it, do just that - render the form out to the browser again, with whatever validation errors/prepopulation/whatever you want to display.

Related

Problem redirecting and using gorilla sessions in golang

Hello everyone I ask for help because I have a problem when I want to redirect and save sessions with gorilla sessions, I have a url which validates an http post request, and this is the code:
if err != nil {
// here i create a session using gorilla sessions with a function that i created
flash := NewFlashSession("errors", c)
// and here i set the error with a function that i also created
flash.Set("general", "Error :(")
// and i guess this is where the error starts
flash.Save()
http.Redirect(r.Writer, r.Request, "url", statusCode)
}
Actually I have a bit more complex model to explain it all in this question, but in summary what the "flash.Save()" function does is use the ".Save()" method of gorilla sessions, which receives an object "*http.Request" and "http.ResponseWriter".
And the variable "err" is an error caused by some error in validation, but when an error occurs and I want to redirect, I get the following error:
http: superfluous answer. WriteHeader call
And after doing some research, I realized that this was the cause of the problem, but. How can I save a session using Gorilla Sessions and then do a redirect? Or is there any other way to do it?
I hope you have understood me, if I do not explain myself well or if you need more information, I will try to show more of the code, I did not do it because it seems to me that the error is when I save the session and then do the redirection, and it seems to me needless to show the rest of the code. Thank you in advance :D.
I tried your code, and as they put in the comments, when adding a return there is no longer an error:
if err != nil {
// here i create a session using gorilla sessions with a function that i created
flash := NewFlashSession("errors", c)
// and here i set the error with a function that i also created
flash.Set("general", "Error :(")
// and i guess this is where the error starts
flash.Save()
http.Redirect(r.Writer, r.Request, "url", statusCode)
return;
}

Retain original URL in redirect error message

I'm trying to determine if a webpage exists on a particular website, by sending a GET request to the specific page. However, if the webpage doesn't exist, the website redirects the request to the home page.
To overcome this, I've implemented the redirection prevention, as stated here, which looks something like
func RedirectCheck(req *http.Request, via []*http.Request) error {
if req.Response.StatusCode == 200 {
// no redirection occured
return nil
}
// return error code
return errors.New("webpage doesn't exist")
}
The redirection prevention works fine, but, if I made a get request to https://someurl.com/page1, the error message that I recieve is
Get "https://someurl.com": webpage doesn't exist
How do I configure the error message so that the original URL is retained in the error message?
The error message should then be
Get "https://someurl.com/page1": webpage doesn't exist
The Client.CheckRedirect documentation says:
As a special case, if CheckRedirect returns ErrUseLastResponse,then the most recent response is returned with its body unclosed, along with a nil error.
Fix by returning ErrUseLastResponse from the function:
func RedirectCheck(req *http.Request, via []*http.Request) error {
return http.ErroUseLastResponse
}

Removing custom error from MessageBag Laravel

I am trying to display a custom error message when the user who is trying to log in isn't registered in my website. I have this code for that.
if (!(User::where('nickname',$request->input('nickname'))->exists())) {
// adding a custom error if user with such nickname doesn't exist
$errors = new MessageBag;
$errors->add('noExist', 'User with such nickname doesnt exist');
return view('login')->withErrors($errors)->with('title','Login');
}
The error prints, but i want to remove it from my MessageBag, so it won't be displayed after a refresh. How can I achieve this?
If you return a view() in a POST method, like the Controller function handling a login attempt, any subsequent refreshes will simply re-submit the form. For this reason, the ErrorBag won't refresh as you'd expect (return to default state). To get around this, use a proper redirect() to handle re-rendering the view():
// return view('login')->withErrors($errors)->with('title','Login');
return redirect("/login")->withErrors($errors);
$errors will be passed from the POST request back to the GET request handling the display of the login view, and on refresh, will be cleared.

How to handle application errors for json api calls using CakePHP?

I am using CakePHP 2.4.
I want my frontend make api calls to my CakePHP backend using ajax.
Suppose this is to change passwords.
Change password action can throw the following application errors:
old password wrong
new password and confirm new passwords do not match
In my frontend, I have a success callback handler and a error callback handler.
The error callback handler handles all the non 200 request calls such as when I throw NotFoundException or UnAuthorizedAccessException in my action.
The success callback handler handles all the 200 request calls including of course, the above 2 scenarios.
My questions are:
Should I continue to do it this way? Meaning to say, inside all success callback handler, I need to watch out for application success and application error scenarios.
Should I send application errors back with actual HTTP error codes?
if I should do 2, how do I implement this in CakePHP?
Thank you.
Don't use http error codes for system errors like:
old password wrong
new password and confirm new passwords do not match
etc etc...
Now using success handler you can show messages and code flow as:
Create Ajax post or get to submit the form, I am showing you post example
var passwordValue = $('#password').val();
$.post( "/updatePassword", { passwordText: passwordValue })
.done(function(response) {
if(response.status === 'Success'){
// Success msg
// whatever
}else{
// Error msg
// whatever
}
});
json response would like:
{
"status": "Failed/Success",
"message": "old password wrong."
}
Create one function in controller
public function updatePassword() {
$myModel = $this->MyModel->find('first' // YOUR CODE LOGIC);
if($this->request->is('ajax') {
$this->layout=null;
// What else?
echo json_encode($myModel);
exit;
// What else?
}
}
Do something like this, hope it will solve your query!

Go HTTP handler - handling more than two form actions

I have a webapp where I have code like:
func handler (w res, r req) {
if req.Method == POST {
// create html form 2 with a submit button2
return ;
}
// create html form 1 with a submit button1
return
}
func main() {
handle("/", handler)
}
Now, the root / is registered with the handler func. In the first request (GET), I create a form and send it to the user. If the user submits this form, I handle it under the "POST" method. Now, I create a different form in the post method handler, and now I want a way to do some operations based on what the user typed in this form2, when [s]he submits form2.
What is the standard way with go to handle the form2 form submission ? I have done some asp programming earlier and we use form action to submit to a different asp file. How can I do some actions based on parsing the form2 submission request ?
If I'm understanding you correctly, you want a way of routing the same URL to different handlers based on the request method rather than just the path? If that's the case...
For comparison, using Python + Django, the way you're doing this is pretty standard:
def my_django_view(request):
if request.method == "POST":
try_to_process_posted_data()
elif request.method == "GET":
show_a_form_to_user()
If you are trying to do fancier things like URL routing based on path and request method (GET, POST, DELETE, ...), then you might be interested in something like Gorilla.mux
It provides some friendly URL routing methods:
func main() {
router := mux.NewRouter()
router.HandleFunc("/", YourGETHandlerFunc).Methods("GET")
router.HandleFunc("/", YourPOSTHandlerFunc).Methods("POST")
http.Handle("/", router)
}
If you're looking for more resources for web development...
Mango: http://paulbellamy.com/2011/05/introducing-mango/
Web.go: http://www.getwebgo.com/tutorial
Twister: https://github.com/garyburd/twister/blob/master/examples/hello/main.go

Resources