Links in EXM emails are broken for some users - sitecore

We experience the following problem: when we send an email via EXM, links inside the email body doesn't work for some users.
Links inside email body are always converted by default to something like:
http://domainname/sitecore/RedirectUrlPage.aspx?ec_contact_id=xxxx84B137D2037C7D180&ec_message_id=xxxxB4CEAA3FD1A3B&ec_url=%2fthelinkpath
that is obviously done for tracking reasons.
However, some users experience 404 error when navigate the link. The Log always says the following:
ERROR EmailCampaign: Object reference not set to an instance of an object.
Exception: System.NullReferenceException
Message: Object reference not set to an instance of an object.
Source: Sitecore.Analytics
at Sitecore.Analytics.Tracking.StandardSession.InitializePage(ICurrentPageContext currentPageContext, ICurrentPageContext oldPage)
at Sitecore.Analytics.Tracking.StandardSession.Identify(String userName)
at Sitecore.Modules.EmailCampaign.Core.Pipelines.RedirectUrl.IdentifyContact.Process(RedirectUrlPipelineArgs args)
at (Object , Object[] )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at Sitecore.Modules.EmailCampaign.UI.RedirectUrlPage.HandleMessageEvent(ID messageId, ID contactId)
at Sitecore.Modules.EmailCampaign.UI.MessageEventPage.OnLoad(EventArgs e)
The only way to fix this error for the user is to clear his cookies or use another browser or use incognito mode. The user is currently logged out from the website.
Sitecore version 8.0 + EXM
Has anyone faced this problem before?

Indeed, this is because of cookies stored from previous sessions, thanks Tchami.
Sitecore Support answer was the same:
This error occurs when you open multiple mails with multiple
contactId's in the same browser.
But they didn't propose any solution except for clearing cookies or using another browser.
However, we don't want to break user experience even for this rarely appeared cases.
So, in order to handle the exception, we have found that the following pipeline processor should be rewritten:
<processor type ="Sitecore.Modules.EmailCampaign.Core.Pipelines.RedirectUrl.IdentifyContact, Sitecore.EmailCampaign" />
You can have a look at the code of custom processor here.

Related

How to prevent error message after custom UI in Sitecore

I've built a content editor XML UI element. I launch it via a command with the code
string url = Sitecore.UIUtil.GetUri("control:CloneToMarkets") + "&id=" + HttpUtility.UrlEncode(id) + "&path=" + HttpUtility.UrlEncode(path) + "&database=" + HttpUtility.UrlEncode(database);
Context.ClientPage.ClientResponse.ShowModalDialog(url, "400px", "700px", string.Empty, true);
In my DialogForm class I'm overriding OnLoad() and OnOK(). With on load I'm invoking its base method at the start of the class, and OnOk ends with the base method.
If I "ok", "cancel" or "X" on the custom DialogForm I get this error:
My dialog works fine, and completes its purpose, I'm just getting this error afterwards. Does anyone know what causes this?
I believe that you experience a known problem when Sitecore Client users get mistakenly categorised as robots.
Usually, it happens when Sitecore Analytics is enabled and users do not visit the site front-end before logging into the Sitecore Client. In this situation, the current session may be mistakenly identified as a robot visit and will cause the admin session expiration as Sitecore Analytics reduces session timeout for robot visits aiming to minimise the server resources utilisation.
So, make sure that Sitecore.Analytics.Tracking.RobotDetection.config is disabled on your CM instance and also make the following changes in web.config:
In system.web/httpModules node, name="MediaRequestSessionModule" change the following line from
"Sitecore.Analytics.RobotDetection.Media.MediaRequestSessionModule, Sitecore.Analytics.RobotDetection"
to "Sitecore.Analytics.Media.MediaRequestSessionModule, Sitecore.Analytics".
In system.webServer/modules node, name="MediaRequestSessionModule" change the following line from
"Sitecore.Analytics.RobotDetection.Media.MediaRequestSessionModule, Sitecore.Analytics.RobotDetection"
to "Sitecore.Analytics.Media.MediaRequestSessionModule, Sitecore.Analytics".
Also, take a look at similar posts here:
Your session may have been lost due to a time-out or a server failure. in Sitecore 8.1
https://sitecore.stackexchange.com/questions/6383/can-sitecore-be-customized-to-auto-save-pages-including-the-rich-text-editor

django error reporting request url - how to use this locally?

I have a django project which used the normal email admins on an unhandled exception when debug is set to False. ie in production.
I normally just review the error message and the stack trace. However I clicked on the request url link, which managed to recreate the error on the prouduction site (which then fired off another email).
What is this request url? Does it recreate the full http request (including the session etc..) which resulted in the original error?
Can I get the link to point to a local version of the site? (As after fixing a previous error clicking on the earlier request url has manged to create a recent error that we have been unable to reproduce, so it would be good to recreate this locally so it can be debugged.

When to use messages or 404 in django

I have a doubt when using django.contrib.messages or showing a 404 page. In which case do I should use one or the another?
serial = get_object_or_404(SerialNumber, serial_number=sn)
or
try:
serial = SerialNumber.objects.get(serial_number=sn)
except SerialNumber.DoesNotExist
messages.add_message(request, messages.WARNING, 'no found!')
Thanks in advance!
Let's say you have some url like this:
/article/<pk>/
If a end-user calls /article/5/ and there is no article with ID 5, then you should not only return a message, that the searched term is not found, but also the proper HTTP status code, which is 404. Here you should use get_object_or_404.
If you want to display some additional information on the page for /article/4/ and there is article with ID 4, but this particular additional information is not there, then you should display the page for article with ID 4, return HTTP status code 200, which means OK, and display the message, that the additional information is not available.
The main difference is in my opinion the proper handling of the HTTP status codes, but I let others teach me, if I'm wrong.
In my opinion, the main difference between 404 error and Django messages framework is that the 404 is related to the server, and messages are related to your application.
In other words, if a user requires an url which does not exist (ie. /url/which/doesnt/exist/) then the server should send a 404. But if a user requires a feature of your application which can fail or which gives info or debug messages (/articles/feature_acting_on_article_db/), then you should use messages framework.
As you can see in documentation https://docs.djangoproject.com/en/1.7/ref/contrib/messages/, messages are used at application level. The definition of 404 error is given by: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5:
(...)This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.
To conclude, I would say that the proper way to handle a url like /article/5/ where there is no 5th article is to send a message, because /article/pk/ is a feature which selects and displays info of the pk'th article (and no article doesn't mean that the command failed), even if the user entered a url (but that's my point of view about this question).
A 404 page page should be displayed when the user is trying to access any resource that is not available on the server.
On the other hand django messaging is used when you want to let the user see your application related custom messages. for example when he deletes or updates an entry you can show him a delete/update successful message.

HTTP status for different conflict scenarios

I'm implementing user registration for a Web Service.
When somebody wants to register an account, my WS sends an activation link to his/her mail. Until this link is clicked, user account is not activated (but the info is persisted in database, so the resource exists).
So my question is, if you try to register the same mail several times, you will get a 409 CONFLICT code. But there are two scenarios right there:
User account pending on confirmation
User already registered and activated
I would like to know what is the right approach. Should I "invent" an HTTP status 4XX to distinguish them, or send 409 with a JSON with info? other solutions?
Thx!
EDIT:
I have found this response -> https://stackoverflow.com/a/3290369/1171280 where Piskvor suggest to use 409 status and request header to explain the reason why it failed and/or body. Which one? header? body? both?
What do you think?
EDIT 2:
HTTP status + body with detailed error (with machine-parseable codes even) is OK, Twitter does that (https://dev.twitter.com/docs/error-codes-responses) and RESPECT :) . But I still doubt with 403 vs 409... :S
Pending account is a special type of a user account, so I think both accounts (already registered and pending) are same in the context of your question. You should return 409 in both cases. For the REST API both are same cases because that resource already exists in the system.
Regarding your updated question, I would suggest using body (JSON) to send out error(s) instead of using a custom HTTP header to explain the reason why the call failed. Reason is that in the body can you have multiple error messages (each one as a separate JSON object/array element) where as in the header you can have only one (though you can split based on some character). Other reason is that you can have one generic error handling method which looks for an "error" object in the JSON instead of looking for different custom headers for each failure scenario.
HTTP codes:
403 - The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be
repeated.
409 - The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in
situations where it is expected that the user might be able to resolve
the conflict and resubmit the request.
I think it should be 409 because the conflict can be resolved by re-issuing the request with different email address.
HTTP status codes are not meant to "invented".
409 CONFLICT sounds OK to me. Including details in the body ist OK, too, if your client needs to know.
Don't use 409. Use 403.
[409] is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request.
It's for a request that should have been OK, but has a problem that can be resolved. If you edit a document and PUT the revised text but someone else did the same thing before you did, you should have a chance to look at the other person's work so you don't accidentally undo all their work. You'd get a 409 which means, if you want to revise it, you should send your revision with an indication that you've seen the latest revision by the other person -- i.e. you know what you're doing.
There's no way to 'correct' a redundant attempt to register. The only way to avoid the conflict is to register with a different username, but that's very incorrect.
I'm imagining a POST request that takes a username and email address and creates a new resource dedicated to that new user (which should now be used for validation), sending that resource's URL in an email. So you're dealing with the refusal of the POST request handler to create a new resource, for a reason specific to the business model of your application (rather than an HTTP-related reason like bad syntax).
There's no status code more specific to what you want than 403. In this case, all you should use HTTP's vocabulary to communicate is 'that's not allowed' -- use the layer on top of HTTP to communicate why, like a polite HTML page or a JSON object for the client to understand and render as a polite HTML page.
409 should be ok; for the details https://datatracker.ietf.org/doc/html/draft-nottingham-http-problem-04 might be of interest.

OAuthException (#368) The action attempted has been deemed abusive or is otherwise disallowed

I'm trying to post a feed on my wall or on the wall on some of my friends using Graph API. I gave all permissions that this application needs, allow them when i make the request from my page, I'm having a valid access token but even though this exception occurs and no feed is posted. My post request looks pretty good, the permissions are given. What do I need to do to show on facebook app that I'm not an abusive person. The last think I did was to dig in my application Auth Dialog to set all permission I need there, and to write why do I need these permissions.
I would be very grateful if you tell me what is going on and point me into the right direction of what do I need to do to fix this problem.
Had the same problem. I figured out that Facebook was refusing my shortlinks, which makes me a bit mad...but I get the point because its possible that shortlinks can be used to promote malicious content...so if you have shortlinks as part of your test, replace them w the full url...
I believe this message is encountered for one of the two reasons :
Your post contains malicious links
You are trying to make a POST request over a non-https connection.
The second one is not confirmed but I have seen that behavior. While same code in my heroku hosted app worked fine, it gave this #368 error on my 000webhost hosted .tk domain which wasn't secured by SSL
Just in case anyone is still struggling with this, the problem occurs when you put URLs or "action links" that are not in your own app domain, if you really need to post to an extarnal page, you'll have to post to your app first, then redirect from there using a script or something. hope that helps.
also it's better in my opinion to use HTTPS links, as sometimes i've seen a behaviour where http links would be rejected, but that's intermittent.
I started noticing that recently as well when running my unit tests. One of the tests I run is submitting a link that I know Facebook has blocked to verify that I handle the error correctly. I used to get this error:
Warning: This Message Contains Blocked Content: Some content in this message has been reported as abusive by Facebook...
But starting on July 4th, I started receiving this error instead:
(#368) The action attempted has been deemed abusive or is otherwise disallowed'
Both errors indicate that Facebook doesn't like what you're publishing.