Supress Error messages in Symfony/Twig? - symfony

How can I suppress error messages in a symfony controller / swift message, e.g. if the email of the user doesn't exist, something is wrong with the smpt server or the email address simply doesn't comply with RFC 2822.
For example, we got following CRITICAL error...
request.CRITICAL: Swift_RfcComplianceException: Address in mailbox given [ xxx#xxx.com ] does not comply with RFC 2822, 3.6.2. (uncaught exception) at $
... the user then get's a symfony error page "An Error occured" which I need to suppress in any case.
A simple #$this->get('mailer')->send($message); doesn't work here unfortunately ...
protected function generateEmail($name)
{
$user = $this->getDoctrine()
->getRepository('XXX')
->findOneBy(array('name' => $name));
if (!$user) {
exit();
}
else {
$message = \Swift_Message::newInstance()
->setSubject('xxx')
->setFrom(array('xxx#xxx.com' => 'xxx'))
->setTo($user->getEmail())
->setContentType('text/html')
->setBody(
$this->renderView(
'AcmeBundle:Template:mail/confirmed.html.twig'
)
)
;
$this->get('mailer')->send($message);
// a simple #$this->get('mailer')->send($message); doesn't work here
}
return true;
}

To simply suppress the error, wrap the send method in a try-catch block. Choose the exception type wisely. The following example just catches Swift_RfcComplicanceExceptions.
try {
$this->get('mailer')->send($message);
} catch (\Swift_RfcComplianceException $exception) {
// do something like proper error handling or log this error somewhere
}
I'd consider it advisably to apply some validation beforehand, so you can display a nice error to your user.

I'm not sure that a try catch block will work, because mails may be sent later in the request process : http://symfony.com/fr/doc/current/components/http_kernel/introduction.html#l-evenement-kernel-terminate
If you use the framework Full Stack edition, this is the default behavior.
I've also found some refs here : Unable to send e-mail from within custom Symfony2 command but can from elsewhere in app
You can change the Swiftmailer spool strategy in your config to send direct mails...

Related

Meteor publication send custom sanitized error to client in publication

I am not sure if I am just doing something wrong or if this is actually not working. I want to display the original publication error on the client, in case I catched one:
Meteor.publish('somePub', function (args) {
const self = this
try {
// ... publication logic
catch (pubErr) {
self.error(pubErr)
}
})
On the client I am "catching" this error via the onStop callback:
Meteor.subscribe('somePub', args, {
onStop: function (e) {
// display e to user
}
})
However, while on the server the pubErr is a Meteor.Error and according to the documentation it should be sent to the client, the client just receives a generic sanitized error message:
on the server
{
stack: "useful stack of actual method calls",
error: "somePub.failed",
reason: "somePub.invalidArguments",
details: { arg: undefined }
}
on the client
{
stack: "long list of ddp-message calls",
isClientSafe: true,
error: 500,
reason: "Internal server error",
details: undefined,
message: "Internal server error [500]",
errorType: "Meteor.Error"
}
Note: I also tried to add the error to itself as sanitizedError field, as in the documentation mentioned, but no success either.
Am I missing something here?
Actually I found the answer to the issue after being pointed into the right direction.
The example code works fine on a new project, so I checked why not in my project and I found, that I did not surround the arguments validation using SimpleSchema by the try/catch (unfortunately my question was poorly designed as it missed this important fact, mainly because I abstracted away the schema validation from the publication creation):
Meteor.publish('somePub', function (args) {
pubSchema.validate(args) // throws on fail
const self = this
try {
// ... publication logic
catch (pubErr) {
self.error(pubErr)
}
})
So I thought this could not be the issue's source but here is the thing: Simple Schema is not a pure Meteor package but a NPM package and won't throw a Meteor.Error but a custom instance of Error, that actually has the same attributes (error, errorType, details) like a Meteor.Error, see this part of the source code of a validation context.
So in order to pass the correct information of a SimpleSchema validation error to the client you should
wrap it in a try/catch
add the isClientSafe flag to it
alternatively convert it to a Meteor.Error
Attach a custom Meteor.Error as sanitizedError property to it

App maker override server side error message

I have a problem with the server-side error management on Google App Maker.
Here an exemple of my code
Server-side
function serverSideFn() {
// Consider the error to be throw.
if ( anError ) {
throw new Error("A specific error message");
}
}
Client-side
function clientSideFn() {
google.script.run
.withSuccessHandler(function(result) {
// Success code...
})
.withFailureHandler(function(error) {
console.log(error.message); // The message error here is not the same if I have or not the Admin role.
showErrorPopup(error.message);
})
.serverSideFn();
}
When I execute the "clientSideFn" function with default role Admin, I have the good message ("A specific error message"), but if I don't have the Admin role, I have a "Server Error" message instead of the expected.
I've tried to use the developer account option, and set Admin role to this account and execute the server side scripts, but the error is still present for users without Admin role.
I've also tried to throw a custom Exception, but the error is still changed on client side.
What I can change to got the expected message when the user don't have the Admin role ?
The relevant documentation to your question is located here https://developers.google.com/appmaker/scripting/api/server. The basics is that you use:
throw new app.ManagedError('Your custom message here');

How to handle exception inside an EventListener class in Symfony

On the onRegistrationSuccess method of an EventListener class, I have an api call that registers a user into another system.
$response = $this->service->postCustomer($customer)
if (200 !== $response->getCode() {
$response = new RedirectResponse($event->getRequest()->getPathInfo());
$event->setResponse($response);
}
My question is, what is the best way to catch the error or display it on the same page? example the route is on /user/register the response is a validation error. Cause right now it still redirects the use to the check email page.
Btw im using FOSUserBundle. Im really new in Symfony so im really not aware on what's the best way to do it
Thank you!
You need to increase the priority of your listener as described in the documentation, otherwise the listener responsible for email confirmation page fires earlier
public static function getSubscribedEvents()
{
return [
FOSUserEvents::REGISTRATION_SUCCESS => [
['onRegistrationSuccess', 10],
],
];
}
You can use flash messages to show the error as was suggested by #MohamedRadhiGuennichi
Subscribing to FOSUserEvents::REGISTRATION_SUCCESS means that the user is already stored in your database, so you should rollback this in case of an error.

Authentication and Custom Error pages

I have a site that is using Azure ACS for authentication, backed by ADFS. When things are going well and people do things they are supposed to its great but that doesn't happen always so we have been implementing custom error pages.
The problem is, it doesn't seem to catch authentication errors, such as
ID3206: A SignInResponse message may only redirect within the current web application
Key not valid for use in specified state.
These errors still produce the ugly yellow error screen no matter what I say in my web.config. They are clearly ASP.NET errors and not IIS errors, so my question is how and where can I put custom error pages to display such errors in a 'pretty' way, as setting a page in web.config isn't working?
EDIT: To be clear, we have ACS set up to use an error page, have customErrors on with a different error page, neither or being used.
You have to have an action on a controller in your web app that accepts a POST from ACS and takes a parameter of type string. You must also configure your relying party application in ACS to point to that action for errors. Then in the action code you can do something like this:
namespace ASPNETSimpleMVC.Controllers
{
public class ErrorController : Controller
{
// Errors can be mapped to custom strings here.
static Dictionary<string, string> ErrorCodeMapping = new Dictionary<string, string>();
static ErrorController()
{
ErrorCodeMapping["ACS50019"] = "You chose to cancel log-in to the identity provider.";
ErrorCodeMapping["ACS60001"] = "No output claims were generated. You may be unauthorized to visit this site.";
}
//
// POST: /Error/
//
// If an error occurs during sign-in, ACS will post JSON-encoded errors to this endpoint.
// This function displays the error details, mapping specific error codes to custom strings.
[AcceptVerbs( HttpVerbs.Post )]
public ActionResult Index( string ErrorDetails )
{
// The error details contain an array of errors with unique error codes to indicate what went wrong.
// Additionally, the error details contain a suggested HTTP return code, trace ID, and timestamp, which may be useful for logging purposes.
ErrorDetails parsedErrorDetails = new JavaScriptSerializer().Deserialize<ErrorDetails>( ErrorDetails );
ViewData["ErrorMessage"] = String.Format( "An error occurred during sign-in to {0}. ", parsedErrorDetails.identityProvider );
// Loop through all ACS errors, looking for ones that are mapped to custom strings.
// When a mapped error is found, stop looking and append the custom string to the error message.
foreach ( ErrorDetails.Error error in parsedErrorDetails.errors )
{
if ( ErrorCodeMapping.ContainsKey( error.errorCode ) )
{
ViewData["ErrorMessage"] += ErrorCodeMapping[error.errorCode];
break;
}
}
return View( "Error" );
}
}
}
You may also find this article helpful.

Extending Access Token Expiration not functioning

I am at the intermediate level in php and am new with facebook development. I have looked through the facebook documents and Stack Overflow previous comments.
All I basically wanted to do was let the user log in with their Facebook account and display their name.
My php page has a graph, and the page auto refreshes every 2 or 5 min.
I authenticate and get the facebook first_name to put on the page.
$graph = $facebook->api('/me');
echo $graph['first_name'] to get the first name of the user .. (for which I thought that no access token was required).
After about 90 min. I have been receiving the error:
fatal error: Uncaught OAuthException: An active access token must be used to query information about the current user......
and I have no value ( 0 ), in the $facebook->getUser(); parameter
I do know that off line access permission has been depreciated, (and I have have this enabled in my apps advanced settings)
I am trying to get an extended access token. In the FB docs. I see:
https://graph.facebook.com/oauth/access_token?
client_id=APP_ID&
client_secret=APP_SECRET&
grant_type=fb_exchange_token&
fb_exchange_token=EXISTING_ACCESS_TOKEN
I included my information in the link(an existing valid access token and all) and received a access token:
access_token=AAADbZBPuUyWwBAFubPaK9E6CnNsPfNYBjQ9OZC63ZBN2Ml9TCu9BYz89frzUF2EnLttuZAcG2fWZAHbWozrvop9bQjQclxVYle7igvoZCYUAg2KNQLMgNP&expires=4050
Yet this token expired in about 1 hour or so.(....expires=4050)
I assume I am using server side auth because I am using PHP?
I assume you need to enable "deprecate offline_access" in your Apps Advanced Settings page. As this worked for me:
//added code in base_facebook.php inside the facebook class
public function getExtendedAccessToken(){
try {
// need to circumvent json_decode by calling _oauthRequest
// directly, since response isn't JSON format.
$access_token_response =
$this->_oauthRequest(
$this->getUrl('graph', '/oauth/access_token'),
$params = array( 'client_id' => $this->getAppId(),
'client_secret' => $this->getAppSecret(),
'grant_type'=>'fb_exchange_token',
'fb_exchange_token'=>$this->getAccessToken(),
));
} catch (FacebookApiException $e) {
// most likely that user very recently revoked authorization.
// In any event, we don't have an access token, so say so.
return false;
}
if (empty($access_token_response)) {
return false;
}
$response_params = array();
parse_str($access_token_response, $response_params);
if (!isset($response_params['access_token'])) {
return false;
}
return $response_params['access_token'];
}
The token can still be invalid for several reasons, See How-To: Handle expired access tokens.
Hope it helps
There's a bug on this:
https://developers.facebook.com/bugs/241373692605971
But, another question on SO has a workaround (user uninstalls and re-installs):
fb_exchange_token for PHP only working once user removes app

Resources