Validate COMPLETE XML Against XSD - java

I want to validate my XML against my XSD COMPLETELY, meaning that I want the file to continue validating from the same point where it had thrown an exception.
This is my code :
public void validate(File file) {
try {
Source xmlFile = new StreamSource(file);
try {
System.out.println("Processing : " + file.getAbsolutePath());
System.out.println(validator);
validator.validate(xmlFile);
// stringBuffer.append(" is valid");
} catch (SAXException e) {
fileWriter.write("\n\n\n" + file.getAbsolutePath());
System.out.println(xmlFile.getSystemId() + " is NOT valid");
System.out.println("Reason: " + e.getLocalizedMessage());
fileWriter.write("\nReason: " + e.getLocalizedMessage());
if (e instanceof SAXParseException) {
fileWriter.write(" (Line : "
+ ((SAXParseException) e).getLineNumber()
+ ", Col : "
+ ((SAXParseException) e).getColumnNumber() + ")");
}
fileWriter.flush();
validate(file);
}
} catch (Exception exception) {
exception.printStackTrace(System.out);
}
}
Here according to this snippet, after JUST ONE EXCEPTION the code returns the error and stops validating further XML.. But is there any way to get all the errors of the XML against the XSD? In short to continue validating from the cursor where it had thrown an exception.
ANY WAY OUT??
Thanks!

The behavior of the default error handler is to stop processing after the first fatal error is encountered by throwing a SAXException. To alter this behavior, implement your own ErrorHandler and register it with your validator.
This is an example that just dumps the exceptions to standard output, but you would probably want to replace it with a more intelligent reporting mechanism.
class CustomErrorHandler implements ErrorHandler {
public void fatalError(SAXParseException e) throws SAXException {
System.out.println(e.toString());
}
public void error( SAXParseException e ) throws SAXException {
System.out.println(e.toString());
}
public void warning( SAXParseException e ) throws SAXException {
System.out.println(e.toString());
}
}
And then:
validator.setErrorHandler(new CustomErrorHandler());

Related

How to handle custom exceptions in Spring Aspect class?

I need to know how can i handle custom exceptions in my Aspect class, so that i can print log out of it?
Below is my Aspect class:
#Around("#annotation(com.aspect.LoggableService)")
public Object ServiceMetrices(ProceedingJoinPoint pjp) throws Throwable {
try {
pjp.proceed();
} catch(CustomException ex) {
// logging exception details here
LOGGER.info("Logs for API Metrices " + pjp.getSignature() + " {} " +
return pjp.proceed();
} catch (Exception ex) {
// Logging exception details
LOGGER.info("Logs for API Metrices " + pjp.getSignature() + " {} " +
return pjp.proceed();
}
I am calling this aspect annotation after the execution from my service class.
try {
//Code
}
catch(HttpClientErrorException x) {
throw new CustomException(x.getStatusCode(),"POST Request failed");
}
I want my exceptions to be handled by my CustomException block in my Aspect class instead of handling it in Exception class.

How to customize the error message for NoSuchElementException in Optional class

I have a method that throws NotFoundException if my object id is null.
public void removeStatementBundleService(String bundleId) throws NotFoundException {
Optional<StatementBundle> bundleOpt = statementBundleRepository.findById(bundleId);
if(bundleOpt.isPresent()) {
StatementBundle bundle = bundleOpt.get();
if(bundle.getStatements() != null && !bundle.getStatements().isEmpty()) {
for(Statement statement: bundle.getStatements()) {
statementRepository.delete(statement);
}
}
if(bundle.getFileId() != null) {
try {
fileService.delete(bundle.getFileId());
} catch (IOException e) {
e.printStackTrace();
}
}
statementBundleRepository.delete(bundle);
} else {
throw new NotFoundException("Statement bundle with id: " + bundleId + " is not found.");
}
}
I found out that this isn't needed since the java.util.Optional class is used. In the oracle documentation I found out that if get() is used and there is no value then NoSuchElementException is thrown. What is the best way I can add my error message to the exception. I am trying to open the Optional class in Eclipse to try change inside it(not sure if this is good practice) but Eclipse will not let me access this class on the other hand I read that this class is also final.
When resolving the Optional value, you can directly throw an Exception if the value is not present:
Optional<StatementBundle> bundleOpt = statementBundleRepository.findById(bundleId);
StatementBundle bundle = bundleOpt.orElseThrow(()
-> new NotFoundException("Statement bundle with id: " + bundleId + " is not found.");
or (single statement):
StatementBundle bundle = statementBundleRepository.findById(bundleId)
.orElseThrow(()
-> new NotFoundException("Statement bundle with id: " + bundleId + " is not found.");
The Optional class does provide a orElseThrow(...) method which takes a Supplier as it's only parameter and therefore allowing us to throw custom exception in case the value is absent.
This enables expressions like:
StatementBundle bundle = bundleOpt.orElseThrow( ()->new NotFoundException("Statement bundle with id: " + bundleId + " is not found.") );
Don't manipulate the NoSuchElementException, wrap it in a custom exception.
try {
try {
// We simulate a failing .get() on an Optional.
throw new NoSuchElementException("message from Optional.get()");
} catch (NoSuchElementException ex) {
// We wrap the exception into a custom exception and throw this.
throw new MyException("my message", ex);
}
} catch (MyException ex) {
// Now we catch the custom exception and can inspect it and the
// exception that caused it.
System.err.println(ex.getClass().getCanonicalName()
+ ": " + ex.getMessage()
+ ": " + ex.getCause().getMessage());
}
Output:
MyException: my message: message from Optional.get()

Why is my 'Wait method' not failing the TestNG test case?

I have purposely changed the element so it is incorrect, but my test doesn't fail in TestNG. Any ideas?
My Code:
public void waitAndClickElement(WebElement element) throws InterruptedException {
try {
element.click();
} catch (TimeoutException timeEx) {
this.wait.until(ExpectedConditions.elementToBeClickable(element)).click();
} catch (StaleElementReferenceException elementUpdated) {
this.wait.until(ExpectedConditions.elementToBeClickable(element)).click();
} catch (Exception e) {
System.out.println("Unable to wait and click on element, Exception: " + e.getMessage());
}
}
#Test(priority = 2)
public void clickOnDrivingExperiencePage() throws Exception {
basePage.waitAndClickElement(homepageHeader.link_DrivingExperiences);
}
New Code Changes:
public void waitAndClickElement(WebElement element) throws InterruptedException {
try {
this.wait.until(ExpectedConditions.elementToBeClickable(element)).click();
System.out.println("Successfully clicked on the WebElement: " + "<" + element.toString() + ">");
} catch (Exception e) {
System.out.println("Unable to wait and click on WebElement, Exception: " + e.getMessage());
Assert.assertFalse(true, "Unable to wait and click on the WebElement, using locator: " + "<" + element.toString() + ">");
}
}
} catch (Exception e) {
System.out.println("Unable to wait and click on element, Exception: " + e.getMessage());
}
You are catching all exceptions, so the test won't fail.

How to make TestNG continue test execution on an exception?

When i get an exception, the test run immediately ends, and any following test validations are skipped. I would like to catch the exception, handle it, then continue the workflow.
In the below example, If objPage.Method1(); throws an exception, the entire #Test immediately ends. I would like the catch to execute, then move on to objPage.Method2().
#Test (enabled=true)
public void MyClientsFunctions() throws Exception {
ExtentTest t = ReportFactory.getTest();
try {
Login objPage = new PageObject(driver);
//this method throws exception
objPage.Method1();
if (x=y)
t.log(LogStatus.PASS, "Pass message");
else
t.log(LogStatus.FAIL,"Fail message"+ screenshotMethod());
objPage.Method2();
if (a=b)
t.log(LogStatus.PASS, "Pass message");
else
t.log(LogStatus.FAIL,"Fail message"+ screenshotMethod());
} catch (Exception e) {
t.log(LogStatus.ERROR, "Exception found: " + e.getMessage() + screenshotMethod());
}
}
I am using PageFactory and ExtentReports. I am use if statements to report failures. No asserts. I believe if an assert fails, the result is the same, and the test ends.
Write the objPage.Method2() in final block then it will execute.
Credit to #JeffC for pointing me in the right direction.
For my case, I have at least a dozen action methods called from the Page Object class. I can't put them all in their own final block.
What I did was put each workflow (one or more methods, then validation) in it's own try/catch. The catch includes logging/screenshot, then redirects to the page that the next workflow needs to execute. So, we try/catch(login), try/catch(enterHoursWorked) etc... As others have said, it's ugly, but in my case it works. Now the exception is added to the log, and the next workflow executes
public void MyClientsFunctions() throws Exception {
ExtentTest t = ReportFactory.getTest();
try {
Login objPage = new PageObject(driver);
// this method throws exception
try {
objPage.Login();
if (x = y)
t.log(LogStatus.PASS, "Pass message");
else
t.log(LogStatus.FAIL, "Fail message" + screenshotMethod());
} catch (Exception e) {
t.log(LogStatus.ERROR, "Exception found: " + e.getMessage() + screenshotMethod());
objPage.BackToHomePage();
}
try {
objPage.EnterHoursWorked();
if (a = b)
t.log(LogStatus.PASS, "Pass message");
else
t.log(LogStatus.FAIL, "Fail message" + screenshotMethod());
} catch (Exception e) {
t.log(LogStatus.ERROR, "Exception found: " + e.getMessage() + screenshotMethod());
objPage.BackToHomePage();
}
} catch (Exception e) {
t.log(LogStatus.ERROR, "Exception found: " + e.getMessage() + screenshotMethod());
}
}

code without log messages

From time to time I come across a class where a bigger part of code are logging calls.
e.g.
public init(Config config) {
logger.info("Configuring ...");
if (config.hasInitInterval()) {
initInterval = config.getInitInterval();
logger.info("Set initInterval to " + initInterval);
}
...
try {
logger.info("Updating access points " + config.getAccessPoints());
updateAccessPoints(config.getAccessPoints())
} catch (Throwable e) {
logger.warn("Init failed due to ", e);
}
...
if (logger.isDebugEnabled ()) {
for(int i = 0; i < config.getModifiers().size(); i++) {
try {
isValidModifier(config.getModifiers().get(i));
} catch (Exception e) {
throw new IllegalArgumentException ("Wrong modifier: " config.getModifiers().get(i));
}
}
}
}
When a class is not formatted well plus contains comments, it's hard to read the code.
I used proxy pattern to partially improve it but it's suitable only to log something before or after a call of method.
What are the best practices to separate functionality from logging?

Categories

Resources