Retain original URL in redirect error message - go

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
}

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;
}

Deleting a non-existing identity in DynamoDB Golang

I am having a golang project where I am using dynamoDB as my backend database. I wanted to return the error when we are trying to Delete a non-existing entity. But the DynamoDB.DeleteItem does not return an error on that thing. Please help me with that.
You can actually do it using the response you will get from DeleteItem method in dynamoDB.
Ex:
resp, err := dynamoDB.DeleteItem(input)
if resp.ConsumedCapacity != nil {
\\entity not found error
}
Actually, the first struct returned by the DeleteItem function is a DeleteItemOutput
There's a comment that addresses how this object would be present
This map appears in the response only if ReturnValues was specified as ALL_OLD in the request.
You can adjust your logic accordingly and it might solve your problem

Render a template upon failed POST request [golang]

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.

Datatables 1.10.5 ajax error handler - Getting access to the http status code

I'm using Datatables 1.10.5 and I have the ajax error handler defined. I need to gain access to the actual http status code when the error fires so I can see if my user's session time has expired (HTTP 401) vs if there's something wrong on the backend such as an HTTP 500 error. Right now the techNote is always 7.
How can I get that elusive HTTP status code from the ajax transaction? I tried below, but it does not fire.
$("#example").ajaxError(function(event, jqxhr, request, settings){
alert("Failure HTTP Code:"+jqxhr.status);
});
and
$.fn.dataTable.ext.errMode = 'throw';
$('#example').on('error.dt', function(e, settings, techNote, message) {
console.log( 'An error has been reported by DataTables: ', message);
});
Does not have the information I need, or at least that I cannot find it in any of the passed variables.
I've been able to get access to the status code without overriding global jQuery ajaxError by overriding the more specific to DataTables $.fn.dataTable.ext.errMode with a function:
$.fn.dataTable.ext.errMode = function (settings, tn, msg) {
if (settings && settings.jqXHR && settings.jqXHR.status == 401) {
window.location = window.location.origin + '/login';
return
}
alert(msg) // Alert for all other error types; default DataTables behavior
};
This example shows a redirect to login on 401 status code, however, you could do the same with any other status code.
Last note is you might want to leverage the DataTables statusCode option for status code specific handling but you'll still need to override $.fn.dataTable.ext.errMode if you want to bypass default error handling since it executes before anything you define in statusCode
Handle xhr event. When Ajax error occurs third argument json would be null and fourth argument xhr would contain jQuery XHR object. You can get the status by accessing xhr.status property.
Also see $.fn.dataTable.ext.errMode which could be used to instruct DataTables not to show the alert.

Redirecting a signal returning an error to another signal

So my use case is that I have an HTTP request (fired using -[NSURLSession rac_dataWithRequest:]) that can return a status code of 403.
When this happens I would like to catch that, and redirect to another SignalProducer that requests an authentication token. When that SignalProducer successfully completes, I would like to redirect back to the original rac_dataWithRequest.
How would I best do this? I'm using ReactiveCocoa 4.x and Swift 2.
do you need to hand the authentication token back to the original request before retrying? If yes, then this won't help you, sorry.
I assumed that you just need to fire the authentication request once and then retry the original request. E.g. your authentication request sets the HTTP Authorization header of your HTTP client so that the next request is automatically authorised...
This gist has the contents of a Playground that illustrates the solution. This gist is the result of me playing around to find a solution, requests are mocked, ...
Lets say you have a SignalProducer for your request:
let request = SignalProducer<Response, NSError> {
// Perform your request that needs authentication here
}
And another one for your authentication request:
let authorize = SignalProducer<Void, NSError> {
// Perform your request that needs authentication here
}
Now you can use flatMapErrors (formerly catch) and retry:
request.flatMapError { error -> SignalProducer<String, NSError> in
if(error.code == 403) {
return authorize.then(SignalProducer(error: error))
} else {
return SignalProducer(error: error)
}
}.retry(1)
So, we catch errors of the original request and, if the error code is 403, we perform the authorize request. Then, we still forward the catched error. Otherwise, we just forward the error.
Forwarding the error after the authorize request is important, otherwise, retry will not restart the original request.
The problem with this however is, that it will retry on every error, not just when the original request returns 403...

Resources