mirror of
https://github.com/apache/poi.git
synced 2026-02-27 20:40:08 +08:00
Add more information in exception when formula parsing fails
Use toString() instead of getClass() to include more information for some ValueEval implementations When low-level parsing fails, the IllegalStateException does not contain any information, therefore wrap it and enrich it with more information about the cell and the parsed formula git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1908608 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
debd3bd4a9
commit
c0484ce62d
@ -57,9 +57,27 @@ public abstract class BaseXSSFFormulaEvaluator extends BaseFormulaEvaluator {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected CellValue evaluateFormulaCellValue(Cell cell) {
|
protected CellValue evaluateFormulaCellValue(Cell cell) {
|
||||||
EvaluationCell evalCell = toEvaluationCell(cell);
|
final ValueEval eval;
|
||||||
ValueEval eval = _bookEvaluator.evaluate(evalCell);
|
try {
|
||||||
cacheExternalWorkbookCells(evalCell);
|
EvaluationCell evalCell = toEvaluationCell(cell);
|
||||||
|
eval = _bookEvaluator.evaluate(evalCell);
|
||||||
|
cacheExternalWorkbookCells(evalCell);
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
// enhance IllegalStateException which can be
|
||||||
|
// thrown somewhere deep down the evaluation
|
||||||
|
// and thus is often missing information necessary
|
||||||
|
// for troubleshooting
|
||||||
|
// do not enhance others to keep the exception-sub-classes
|
||||||
|
// in place
|
||||||
|
if (e.getClass() == IllegalStateException.class) {
|
||||||
|
throw new IllegalStateException("Failed to evaluate cell: " +
|
||||||
|
new CellReference(cell.getSheet().getSheetName(), cell.getRowIndex(), cell.getColumnIndex(),
|
||||||
|
false, false).formatAsString(true) + ", value: " + cell, e);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (eval instanceof NumberEval) {
|
if (eval instanceof NumberEval) {
|
||||||
NumberEval ne = (NumberEval) eval;
|
NumberEval ne = (NumberEval) eval;
|
||||||
return new CellValue(ne.getNumberValue());
|
return new CellValue(ne.getNumberValue());
|
||||||
@ -75,7 +93,9 @@ public abstract class BaseXSSFFormulaEvaluator extends BaseFormulaEvaluator {
|
|||||||
if (eval instanceof ErrorEval) {
|
if (eval instanceof ErrorEval) {
|
||||||
return CellValue.getError(((ErrorEval)eval).getErrorCode());
|
return CellValue.getError(((ErrorEval)eval).getErrorCode());
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Unexpected eval class (" + eval.getClass().getName() + ")");
|
throw new IllegalStateException("Unexpected eval class (" + eval.getClass().getName() + "): " + eval + ", cell: " +
|
||||||
|
new CellReference(cell.getSheet().getSheetName(), cell.getRowIndex(), cell.getColumnIndex(),
|
||||||
|
false, false).formatAsString(true) + ", value: " + cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -17,22 +17,29 @@
|
|||||||
|
|
||||||
package org.apache.poi.xssf.usermodel;
|
package org.apache.poi.xssf.usermodel;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
import org.apache.poi.ss.usermodel.CellType;
|
import org.apache.poi.ss.usermodel.CellType;
|
||||||
|
import org.apache.poi.ss.usermodel.FormulaEvaluator;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
class TestFormulaEval {
|
class TestFormulaEval {
|
||||||
@Test
|
@Test
|
||||||
void testCircularRef() throws IOException {
|
void testCircularRef() throws IOException {
|
||||||
try (XSSFWorkbook wb = new XSSFWorkbook()) {
|
try (Workbook wb = new XSSFWorkbook()) {
|
||||||
XSSFSheet sheet = wb.createSheet();
|
Sheet sheet = wb.createSheet();
|
||||||
XSSFRow row = sheet.createRow(0);
|
Row row = sheet.createRow(0);
|
||||||
XSSFCell cell = row.createCell(0);
|
Cell cell = row.createCell(0);
|
||||||
cell.setCellFormula("A1");
|
cell.setCellFormula("A1");
|
||||||
XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
|
FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
|
||||||
// the following assert should probably be NUMERIC not ERROR (from testing in Excel itself)
|
// the following assert should probably be NUMERIC not ERROR (from testing in Excel itself)
|
||||||
assertEquals(CellType.ERROR, formulaEvaluator.evaluateFormulaCell(cell));
|
assertEquals(CellType.ERROR, formulaEvaluator.evaluateFormulaCell(cell));
|
||||||
|
|
||||||
@ -45,14 +52,14 @@ class TestFormulaEval {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCircularRef2() throws IOException {
|
void testCircularRef2() throws IOException {
|
||||||
try (XSSFWorkbook wb = new XSSFWorkbook()) {
|
try (Workbook wb = new XSSFWorkbook()) {
|
||||||
XSSFSheet sheet = wb.createSheet();
|
Sheet sheet = wb.createSheet();
|
||||||
XSSFRow row = sheet.createRow(0);
|
Row row = sheet.createRow(0);
|
||||||
XSSFCell cell0 = row.createCell(0);
|
Cell cell0 = row.createCell(0);
|
||||||
XSSFCell cell1 = row.createCell(1);
|
Cell cell1 = row.createCell(1);
|
||||||
cell0.setCellFormula("B1");
|
cell0.setCellFormula("B1");
|
||||||
cell1.setCellFormula("A1");
|
cell1.setCellFormula("A1");
|
||||||
XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
|
FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
|
||||||
formulaEvaluator.evaluateAll();
|
formulaEvaluator.evaluateAll();
|
||||||
|
|
||||||
cell0.setCellFormula(null);
|
cell0.setCellFormula(null);
|
||||||
@ -64,4 +71,56 @@ class TestFormulaEval {
|
|||||||
assertEquals(CellType.ERROR, cell1.getCellType());
|
assertEquals(CellType.ERROR, cell1.getCellType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testExceptionForWrongFormula1() throws IOException {
|
||||||
|
try (Workbook wb = new XSSFWorkbook()) {
|
||||||
|
Sheet sheet = wb.createSheet("test-sheet");
|
||||||
|
Row row = sheet.createRow(0);
|
||||||
|
Cell cell0 = row.createCell(0);
|
||||||
|
Cell cell1 = row.createCell(1);
|
||||||
|
cell0.setCellValue(1);
|
||||||
|
cell1.setCellFormula("'Sheet123'!R6C13");
|
||||||
|
|
||||||
|
FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
|
||||||
|
try {
|
||||||
|
formulaEvaluator.evaluateAll();
|
||||||
|
fail("Should catch exception here");
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
assertTrue(e.getMessage().contains("test-sheet"),
|
||||||
|
"Had: " + e.getMessage());
|
||||||
|
assertTrue(e.getMessage().contains("Sheet123"),
|
||||||
|
"Had: " + e.getMessage());
|
||||||
|
assertTrue(e.getMessage().contains("R6C13"),
|
||||||
|
"Had: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testExceptionForWrongFormula2() throws IOException {
|
||||||
|
try (Workbook wb = new XSSFWorkbook()) {
|
||||||
|
Sheet sheet = wb.createSheet("test-sheet");
|
||||||
|
Row row = sheet.createRow(0);
|
||||||
|
Cell cell0 = row.createCell(0);
|
||||||
|
Cell cell1 = row.createCell(1);
|
||||||
|
cell0.setCellValue(1);
|
||||||
|
cell1.setCellFormula("SUM('asldkjasldk ajd Sheet123'!R6C13)");
|
||||||
|
|
||||||
|
FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
|
||||||
|
try {
|
||||||
|
formulaEvaluator.evaluateAll();
|
||||||
|
fail("Should catch exception here");
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
assertTrue(e.getMessage().contains("test-sheet"),
|
||||||
|
"Had: " + e.getMessage());
|
||||||
|
assertTrue(e.getMessage().contains("Sheet123"),
|
||||||
|
"Had: " + e.getMessage());
|
||||||
|
assertTrue(e.getMessage().contains("R6C13"),
|
||||||
|
"Had: " + e.getMessage());
|
||||||
|
assertTrue(e.getMessage().contains("SUM"),
|
||||||
|
"Had: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -225,8 +225,7 @@ public abstract class MultiOperandNumericFunction implements Function {
|
|||||||
missingArgConsumer.accept((MissingArgEval) ve, temp);
|
missingArgConsumer.accept((MissingArgEval) ve, temp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Invalid ValueEval type passed for conversion: ("
|
throw new IllegalStateException("Invalid ValueEval type passed for conversion: " + ve);
|
||||||
+ ve.getClass() + ")");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ConsumerFactory {
|
private static class ConsumerFactory {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user