Handling exceptions from a Method in a dialog that can be model and modeless - exception

This is an extract of a method in CDialog class:
void CDialog1::Method()
{
try
{
// Snip
}
catch (CException* e_)
{
const gsl::not_null<CException*> e{ e_ };
e->ReportError();
e->Delete();
}
catch (const _com_error& e)
{
AfxMessageBox(e.ErrorMessage(), MB_OK | MB_ICONERROR);
}
}
There is no issue with this function when it is ran from an instance of the modal dialog.
But, in another part of my application I load the same dialog as a hidden modeless dialog. And I call the same function. Eg:
void CDialog2::SomeTask()
{
if (m_pDialog1 != nullptr)
{
m_pDialog1->Method();
}
}
In this second scenario there is an issue with Method when an error is encountered. CDialog2 needs to handle the display of the errors from what I understand, because the hidden instance will appear if it shows a messagebox.
How do I get around this? Note that CDialog1 has a boolean method IsHiddenMode so we know if we are running it as a model or not.
What is the easy way to change my methods to cater for both scenarios:
When CDialog1 calls the method in it's modal dialog.
When CDialog2 calls the method using the modeless member variable of CDialog1.
I tend to overcomplicate my explanations so I hope it makes sense.

I adjusted the Method to detect if the dialog was in hidden mode and throw the exception, eg:
catch (const _com_error& e)
{
if (IsHiddenMode())
{
throw;
}
else
{
AfxMessageBox(e.ErrorMessage(), MB_OK | MB_ICONERROR);
}
}
That way, the calling dialog could catch and handle with a try / catch block.

Related

CDHtmlDialog crashes while navigating to pdf after navigating to google

Navigate from www.google.com page to pdf file causes exception in CDHtmlDialog.
This exception is not present while navigating from pages other than google (e.g. www.wikipedia.org).
Overridden "OnBeforeNavigate", "OnNavigateComplete" and "OnDocumentComplete" events. Then found that, in issue scenario, while loading pdf file "OnNavigateComplete" is called twice.
The calling sequence is as follows: OnBeforeNavigate=>OnNavigateComplete=>OnNavigateComplete
As "OnNavigateComplete" is called without calling "OnBeforeNavigate", "m_spHtmlDoc" in CDHtmlDialog does not become NULL and validation causes assertion in "CDHtmlDialog::OnNavigateComplete".
ASSERT(m_spHtmlDoc==NULL);
Header:
class CClientAppDlg : public CDHtmlDialog
cpp:
CClientAppDlg::CClientAppDlg(CWnd* pParent /*=nullptr*/)
: CDHtmlDialog(IDD_CLIENTAPP_DIALOG, 0, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CClientAppDlg::OnBnClickedNavigate()
{
UpdateData(TRUE);
Navigate(m_csNavURL); // Get URL from edit box and navigate
UpdateData (FALSE);
}
void CClientAppDlg::OnBeforeNavigate( LPDISPATCH pDisp, LPCTSTR szUrl)
{
CDHtmlDialog::OnBeforeNavigate(pDisp, szUrl);
}
void CClientAppDlg::OnNavigateComplete( LPDISPATCH pDisp, LPCTSTR szUrl)
{
CDHtmlDialog::OnNavigateComplete(pDisp, szUrl);
}
void CClientAppDlg::OnDocumentComplete(LPDISPATCH pDisp, LPCTSTR szUrl)
{
CDHtmlDialog::OnDocumentComplete(pDisp, szUrl);
}
Why "OnNavigateComplete" is called twice and causing exception?
Why does it happen only while navigating from google page?

Avoiding "Other element would receive the click" with elementToBeClickable

I have this method using implicit wait pre configured to return me some WebElement:
private WebElement findElement(By locator) {
WebElement element = null;
for (int i = 0; i <= numberOfTries && element == null; i++)
try {
waiter.until(ExpectedConditions.elementToBeClickable(locator));
element = driver.findElement(locator);
} catch (TimeoutException | NoSuchElementException e) {
System.out.println(specificStringAboutTimeOutAndNoSuchEl);
} catch (WebDriverException e) {
Throwable cause = null;
Throwable result = e;
while (null != (cause = result.getCause()) && (result != cause))
result = cause;
System.out.println(specificStringAboutException);
System.out.println(result);
}
return element;
}
And this to wait to some other element vanish, like spinners and loading screens:
private void waitsElementToVanish(By locator, String previousOp) {
List<Class<? extends Throwable>> ignorableExceptions = new ArrayList<>();
ignorableExceptions.add(StaleElementReferenceException.class);
ignorableExceptions.add(NoSuchElementException.class);
try {
if (driver.findElements(locator).size() > 0)
System.out.println(locator.toString() + " exists");
waiter.ignoreAll(ignorableExceptions).until(ExpectedConditions.visibilityOfElementLocated(locator));
waiter.ignoreAll(ignorableExceptions).until(ExpectedConditions.invisibilityOfElementLocated(locator));
} catch (TimeoutException e) {
System.out.println("timeout waiting " + locator.toString() + " to vanish");
System.out.println(previousOp);
}
}
And I use them like this:
waitsElementToVanish(By.className("spinnerLoading"), "someString");
findElement(By.xpath(otherElement)).click();
And I get this error at .click():
org.openqa.selenium.WebDriverException: unknown error: Element <div class="menuContent ellipsis flex flexGrow">...</div> is not clickable at point (136, 240). Other element would receive the click: <div class="spinnerLoading">...</div>
This is the website I'm using and this application is purely educational. This is the entire code.
Should I wrap Selenium click method into some WebDriverException like:
Tries to click, if WebDriverException is thrown with spinnerClass on it, goes to waitsElementToVanish and then tries again
If number of tries goes beyond limit, then it throws some ReallyMessedUpExceptionDoSomething! exception.
My question is: I want to avoid Thread.sleep() at all costs. I want optimize test time waiting only for what it's coming, not for some pre fixed period without checking anything on page. The 'good practice actions' are really wrap click on many tries? How I can assure I'm avoiding spinner even when the line before tried that too? And I don't see any problem wrapping click on a loop to try again and again with a limit. But, actually, what is the best solution here?

p:dialog show message or reload

In a jsf 2.2 primefaces application, I have a link that opens a dialog that has a form. On submission of the form, I want to close the dialog and reload the current page or show an error on the dialog itself.
The managedbean method is a void method that sets the status using RequestContext - addcallbackparam.
As the dialog submission happens using actionlistener and the remainder of the operation happens in javascript, I can’t quite handle this.
I followed the example provided on primefaces website.
https://www.primefaces.org/showcase/ui/overlay/dialog/loginDemo.xhtml
Can anyone provide any information.
Here is something you can try without using addcallbackparam and javascript..
On validation success, hide the dialog & reload page or on failure, set a warning message as below from managed bean:
public void login(ActionEvent event) {
if(username != null && username.equals("admin") && password != null && password.equals("admin")) {
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.execute("PF('dlg').hide()");
pageReload();
} else {
dialogWarning = "Validation failed";
}
}
public void pageReload() {
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
try {
ec.redirect(((HttpServletRequest) ec.getRequest()).getRequestURI());
} catch (IOException ex) {
//catch and log IO exception here
}
}
In the xhtml dialog set dynamic=true and display the warning message as below and add this id to the update attribute in the Login component.
<h:outputLabel id="warnMsgLabel" value="#userLoginView.dialogWarning" />

Try Catch Bad Practice Flow Control Dilemma

I am aware that doing Flow Control on a program using a try-catch block is bad practice, but I can't see how to do it in another way when the error caught needs a redirection of the code's execution.
For example, let's say I have screen where the user clicks a button, and on the buttons click I execute some code. After the code ends execution, I redirect the user to a new screen....
... But the code execution can failure, and in that case, I need to let the user know of the failure and redirect him to the previous screen.
The way I will do it is (C# example, but I think this is more of a not language related question, more like good practices on coding in general) :
try
{
ExcuteCode(); // Some code that can throw some Exception, it can be a .NET framework method or something else.
NavigateToNextScreen();
}
catch(Exception e)
{
Log.Write(e);
ShowErrorMessage();
GoBack();
}
Even if I change this to:
bool hasError = false;
try
{
ExecuteCode();
}
catch(Exception e)
{
Log.Write(e);
ShowErrorMessage();
hasError = true;
}
if(hasError) { GoBack(); }
else { NavigateToNextScreen();}
It's still doing Flow Control inside the try-catch block.
So, is it there a recommend way to handle this properly and avoid this bad practice?
Are you looking for the obvious?
try
{
if ( ExcuteCode() == false)
{
ShowErrorMessage();
GoBack();
}
else
{
NavigateToNextScreen();
}
}
catch(Exception e)
{
Log.Write(e);
ShowErrorMessage();
// handle critical error
}
Edit
If you have control over ExecuteCode() then instead of throwing an error return a null or false value and use that to check whether to go forward or backward.
Original
What if you always go back after the catch statement and put the go forward code at the end of the try, like this:
try
{
ExecuteCode();
NavigateToNextScreen();
}
catch(Exception e)
{
Log.Write(e);
ShowErrorMessage();
}
GoBack();
Now go back is the default and it only goes forward if everything executes correctly.

NPAPI Plugin[FireFox]: Invoke() / HasProperty() / HasMethod() not getting called

I am developing NPAPI Plugin for Firefox on windows. here is the my java script:
document.addEventListener('load', documentLoad, true);
function loadPlugin(doc)
{
var objWebMon = doc.getElementById("my_firefox");
if(!objWebMon)
{
var objWebMonEmbed = doc.createElement('embed');
objWebMonEmbed.setAttribute('id', 'my_firefox');
objWebMonEmbed.setAttribute('type', 'application/npplugin');
objWebMonEmbed.setAttribute('style', 'height: 10px; width:10px; display:block;');
if(doc.body)
{
doc.body.insertBefore(objWebMonEmbed, doc.body.firstChild);
}
}
}
function documentLoad(event) {
try
{
var doc = event.originalTarget; // doc is document that triggered "onload" event
loadPlugin(doc);
var myplugin = doc.getElementById('my_firefox');
if(myplugin)
{
myplugin();
myplugin.myAction();
}
} catch(err)
{
}
}
as I am calling myplugin()
bool ScriptablePluginObject::InvokeDefault(const NPVariant *args, uint32_t argCount, NPVariant *result)
gets called sucessfully but on calling function myplugin.myAction()
bool ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant *args,
uint32_t argCount, NPVariant *result)
function doesn't called. I have declared myAction inside ScriptablePluginObject::HasProperty(NPIdentifier name) even HasProperty method is not getting called.
Inside catch block i am getting this error. TypeError: fasso.myAction is not a function.
Here are a couple of things to try:
Use an object tag instead of an embed -- I've had more consistent success with object tags, despite the wide popularity of using embed
Never ever ever set the type of an object or embed tag before you add it to the DOM -- doing so causes it to instantiate the plugin and then puts it in a kinda weird state when it gets moved. I don't think this is causing your issue this time, but it's worth trying.
You may need a slight delay between inserting hte plugin into the DOM and using it. Try adding a setTimeout with a delay of 50ms and accessing the plugin in the callback function.
Honestly, #3 is the one I think most likely will make a difference, but I present the other two as they have bitten me on weird things in the past. Good luck!