or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations-and-mapping.mddata-conversion.mdevent-system.mdexception-handling.mdindex.mdreading-operations.mdwriting-operations.md

exception-handling.mddocs/

0

# Exception Handling

1

2

Comprehensive exception hierarchy for different error scenarios during Excel processing. EasyExcel provides structured exception handling that allows for specific error recovery strategies and detailed error reporting.

3

4

## Capabilities

5

6

### Base Exception Classes

7

8

Core exception hierarchy providing foundation for all Excel-related errors.

9

10

```java { .api }

11

/**

12

* Base runtime exception for all Excel operations

13

*/

14

public class ExcelRuntimeException extends RuntimeException {

15

/**

16

* Create exception with message

17

* @param message Error message

18

*/

19

public ExcelRuntimeException(String message);

20

21

/**

22

* Create exception with message and cause

23

* @param message Error message

24

* @param cause Root cause exception

25

*/

26

public ExcelRuntimeException(String message, Throwable cause);

27

28

/**

29

* Create exception with cause

30

* @param cause Root cause exception

31

*/

32

public ExcelRuntimeException(Throwable cause);

33

}

34

35

/**

36

* Common exception for general Excel processing errors

37

*/

38

public class ExcelCommonException extends ExcelRuntimeException {

39

/**

40

* Create exception with message

41

* @param message Error message

42

*/

43

public ExcelCommonException(String message);

44

45

/**

46

* Create exception with message and cause

47

* @param message Error message

48

* @param cause Root cause exception

49

*/

50

public ExcelCommonException(String message, Throwable cause);

51

52

/**

53

* Create exception with cause

54

* @param cause Root cause exception

55

*/

56

public ExcelCommonException(Throwable cause);

57

}

58

```

59

60

### Reading Operation Exceptions

61

62

Exceptions specific to Excel reading operations.

63

64

```java { .api }

65

/**

66

* Exception during Excel analysis/reading operations

67

*/

68

public class ExcelAnalysisException extends ExcelRuntimeException {

69

/**

70

* Create exception with message

71

* @param message Error message

72

*/

73

public ExcelAnalysisException(String message);

74

75

/**

76

* Create exception with message and cause

77

* @param message Error message

78

* @param cause Root cause exception

79

*/

80

public ExcelAnalysisException(String message, Throwable cause);

81

82

/**

83

* Create exception with cause

84

* @param cause Root cause exception

85

*/

86

public ExcelAnalysisException(Throwable cause);

87

}

88

89

/**

90

* Data type conversion errors during reading

91

*/

92

public class ExcelDataConvertException extends ExcelAnalysisException {

93

/**

94

* Row number where error occurred

95

*/

96

private Integer rowIndex;

97

98

/**

99

* Column index where error occurred

100

*/

101

private Integer columnIndex;

102

103

/**

104

* Cell data that failed conversion

105

*/

106

private ReadCellData<?> cellData;

107

108

/**

109

* Create exception with basic information

110

* @param message Error message

111

*/

112

public ExcelDataConvertException(String message);

113

114

/**

115

* Create exception with cell location information

116

* @param rowIndex Row number (0-based)

117

* @param columnIndex Column number (0-based)

118

* @param cellData Cell data that failed conversion

119

* @param message Error message

120

*/

121

public ExcelDataConvertException(Integer rowIndex, Integer columnIndex,

122

ReadCellData<?> cellData, String message);

123

124

/**

125

* Create exception with cell location and cause

126

* @param rowIndex Row number (0-based)

127

* @param columnIndex Column number (0-based)

128

* @param cellData Cell data that failed conversion

129

* @param message Error message

130

* @param cause Root cause exception

131

*/

132

public ExcelDataConvertException(Integer rowIndex, Integer columnIndex,

133

ReadCellData<?> cellData, String message, Throwable cause);

134

135

// Getters for accessing error details

136

public Integer getRowIndex();

137

public Integer getColumnIndex();

138

public ReadCellData<?> getCellData();

139

}

140

```

141

142

### Writing Operation Exceptions

143

144

Exceptions specific to Excel writing operations.

145

146

```java { .api }

147

/**

148

* Exception during Excel generation/writing operations

149

*/

150

public class ExcelGenerateException extends ExcelRuntimeException {

151

/**

152

* Create exception with message

153

* @param message Error message

154

*/

155

public ExcelGenerateException(String message);

156

157

/**

158

* Create exception with message and cause

159

* @param message Error message

160

* @param cause Root cause exception

161

*/

162

public ExcelGenerateException(String message, Throwable cause);

163

164

/**

165

* Create exception with cause

166

* @param cause Root cause exception

167

*/

168

public ExcelGenerateException(Throwable cause);

169

}

170

171

/**

172

* Data conversion errors during writing

173

*/

174

public class ExcelWriteDataConvertException extends ExcelGenerateException {

175

/**

176

* Row number where error occurred

177

*/

178

private Integer rowIndex;

179

180

/**

181

* Column index where error occurred

182

*/

183

private Integer columnIndex;

184

185

/**

186

* Data that failed conversion

187

*/

188

private Object data;

189

190

/**

191

* Create exception with basic information

192

* @param message Error message

193

*/

194

public ExcelWriteDataConvertException(String message);

195

196

/**

197

* Create exception with cell location information

198

* @param rowIndex Row number (0-based)

199

* @param columnIndex Column number (0-based)

200

* @param data Data that failed conversion

201

* @param message Error message

202

*/

203

public ExcelWriteDataConvertException(Integer rowIndex, Integer columnIndex,

204

Object data, String message);

205

206

/**

207

* Create exception with cell location and cause

208

* @param rowIndex Row number (0-based)

209

* @param columnIndex Column number (0-based)

210

* @param data Data that failed conversion

211

* @param message Error message

212

* @param cause Root cause exception

213

*/

214

public ExcelWriteDataConvertException(Integer rowIndex, Integer columnIndex,

215

Object data, String message, Throwable cause);

216

217

// Getters for accessing error details

218

public Integer getRowIndex();

219

public Integer getColumnIndex();

220

public Object getData();

221

}

222

```

223

224

### Flow Control Exceptions

225

226

Special exceptions used for controlling execution flow during processing.

227

228

```java { .api }

229

/**

230

* Exception to stop entire reading process

231

* This is not an error but a control mechanism

232

*/

233

public class ExcelAnalysisStopException extends ExcelAnalysisException {

234

/**

235

* Create stop exception with message

236

* @param message Reason for stopping

237

*/

238

public ExcelAnalysisStopException(String message);

239

240

/**

241

* Create stop exception without message

242

*/

243

public ExcelAnalysisStopException();

244

}

245

246

/**

247

* Exception to stop current sheet reading and continue to next sheet

248

* This is not an error but a control mechanism

249

*/

250

public class ExcelAnalysisStopSheetException extends ExcelAnalysisStopException {

251

/**

252

* Create sheet stop exception with message

253

* @param message Reason for stopping sheet

254

*/

255

public ExcelAnalysisStopSheetException(String message);

256

257

/**

258

* Create sheet stop exception without message

259

*/

260

public ExcelAnalysisStopSheetException();

261

}

262

```

263

264

## Usage Examples

265

266

### Basic Exception Handling in Listeners

267

```java

268

import com.alibaba.excel.context.AnalysisContext;

269

import com.alibaba.excel.event.AnalysisEventListener;

270

import com.alibaba.excel.exception.ExcelDataConvertException;

271

272

public class RobustUserDataListener extends AnalysisEventListener<UserData> {

273

private List<UserData> validUsers = new ArrayList<>();

274

private List<String> errors = new ArrayList<>();

275

276

@Override

277

public void invoke(UserData data, AnalysisContext context) {

278

try {

279

// Validate and process data

280

validateUserData(data);

281

validUsers.add(data);

282

} catch (Exception e) {

283

String error = String.format("Row %d: %s",

284

context.getCurrentRowNum(), e.getMessage());

285

errors.add(error);

286

System.err.println(error);

287

}

288

}

289

290

@Override

291

public void onException(Exception exception, AnalysisContext context) throws Exception {

292

if (exception instanceof ExcelDataConvertException) {

293

ExcelDataConvertException convertException = (ExcelDataConvertException) exception;

294

String error = String.format("Data conversion error at row %d, column %d: %s",

295

convertException.getRowIndex(),

296

convertException.getColumnIndex(),

297

convertException.getMessage());

298

errors.add(error);

299

System.err.println(error);

300

301

// Continue processing instead of stopping

302

return;

303

}

304

305

// For other exceptions, log and continue

306

String error = String.format("Error at row %d: %s",

307

context.getCurrentRowNum(), exception.getMessage());

308

errors.add(error);

309

System.err.println(error);

310

}

311

312

@Override

313

public void doAfterAllAnalysed(AnalysisContext context) {

314

System.out.println("Processing completed:");

315

System.out.println("- Valid users: " + validUsers.size());

316

System.out.println("- Errors: " + errors.size());

317

318

if (!errors.isEmpty()) {

319

System.out.println("Error details:");

320

errors.forEach(System.out::println);

321

}

322

}

323

324

private void validateUserData(UserData data) {

325

if (data.getName() == null || data.getName().trim().isEmpty()) {

326

throw new IllegalArgumentException("Name is required");

327

}

328

if (data.getEmail() == null || !data.getEmail().contains("@")) {

329

throw new IllegalArgumentException("Valid email is required");

330

}

331

if (data.getAge() != null && (data.getAge() < 0 || data.getAge() > 150)) {

332

throw new IllegalArgumentException("Age must be between 0 and 150");

333

}

334

}

335

}

336

```

337

338

### Controlled Reading Termination

339

```java

340

import com.alibaba.excel.context.AnalysisContext;

341

import com.alibaba.excel.event.AnalysisEventListener;

342

import com.alibaba.excel.exception.ExcelAnalysisStopException;

343

import com.alibaba.excel.exception.ExcelAnalysisStopSheetException;

344

345

public class ConditionalStopListener extends AnalysisEventListener<UserData> {

346

private int maxErrors = 10;

347

private int errorCount = 0;

348

private int maxRows = 1000;

349

private int rowCount = 0;

350

351

@Override

352

public void invoke(UserData data, AnalysisContext context) {

353

rowCount++;

354

355

try {

356

// Process data

357

processUserData(data);

358

} catch (Exception e) {

359

errorCount++;

360

System.err.println("Error at row " + context.getCurrentRowNum() + ": " + e.getMessage());

361

362

// Stop if too many errors

363

if (errorCount >= maxErrors) {

364

throw new ExcelAnalysisStopException(

365

"Stopping analysis: too many errors (" + errorCount + ")");

366

}

367

}

368

369

// Stop if processed enough rows

370

if (rowCount >= maxRows) {

371

throw new ExcelAnalysisStopException(

372

"Stopping analysis: reached maximum rows (" + maxRows + ")");

373

}

374

375

// Example of stopping current sheet based on data content

376

if ("END_SHEET".equals(data.getName())) {

377

throw new ExcelAnalysisStopSheetException(

378

"Found end marker, moving to next sheet");

379

}

380

}

381

382

@Override

383

public void doAfterAllAnalysed(AnalysisContext context) {

384

System.out.println("Analysis completed or stopped");

385

System.out.println("Rows processed: " + rowCount);

386

System.out.println("Errors encountered: " + errorCount);

387

}

388

389

@Override

390

public void onException(Exception exception, AnalysisContext context) throws Exception {

391

if (exception instanceof ExcelAnalysisStopException) {

392

System.out.println("Controlled stop: " + exception.getMessage());

393

throw exception; // Re-throw to actually stop

394

}

395

396

// Handle other exceptions without stopping

397

errorCount++;

398

System.err.println("Handled exception: " + exception.getMessage());

399

}

400

401

private void processUserData(UserData data) {

402

// Processing logic that might throw exceptions

403

if (data.getName() == null) {

404

throw new IllegalArgumentException("Name cannot be null");

405

}

406

// Additional processing...

407

}

408

}

409

```

410

411

### Writing Exception Handling

412

```java

413

import com.alibaba.excel.EasyExcel;

414

import com.alibaba.excel.exception.ExcelGenerateException;

415

import com.alibaba.excel.exception.ExcelWriteDataConvertException;

416

417

public class SafeExcelWriter {

418

419

public void writeUsersWithErrorHandling(List<UserData> users, String fileName) {

420

try {

421

EasyExcel.write(fileName, UserData.class)

422

.writeExcelOnException(true) // Write partial data on exception

423

.sheet("Users")

424

.doWrite(users);

425

426

System.out.println("Successfully wrote " + users.size() + " users to " + fileName);

427

428

} catch (ExcelWriteDataConvertException convertException) {

429

System.err.println("Data conversion error during writing:");

430

System.err.println("- Row: " + convertException.getRowIndex());

431

System.err.println("- Column: " + convertException.getColumnIndex());

432

System.err.println("- Data: " + convertException.getData());

433

System.err.println("- Message: " + convertException.getMessage());

434

435

// Try writing with different strategy

436

writeWithFallback(users, fileName);

437

438

} catch (ExcelGenerateException generateException) {

439

System.err.println("Excel generation error: " + generateException.getMessage());

440

441

// Try alternative format

442

writeAsCsv(users, fileName.replace(".xlsx", ".csv"));

443

444

} catch (Exception e) {

445

System.err.println("Unexpected error during writing: " + e.getMessage());

446

e.printStackTrace();

447

}

448

}

449

450

private void writeWithFallback(List<UserData> users, String fileName) {

451

// Implement fallback strategy (e.g., write as plain data without formatting)

452

try {

453

String fallbackName = fileName.replace(".xlsx", "_fallback.xlsx");

454

EasyExcel.write(fallbackName)

455

.sheet("Users")

456

.doWrite(convertToBasicData(users));

457

System.out.println("Fallback write completed: " + fallbackName);

458

} catch (Exception e) {

459

System.err.println("Fallback write also failed: " + e.getMessage());

460

}

461

}

462

463

private void writeAsCsv(List<UserData> users, String fileName) {

464

// Implement CSV writing as alternative

465

try {

466

EasyExcel.write(fileName, UserData.class)

467

.sheet()

468

.doWrite(users);

469

System.out.println("CSV write completed: " + fileName);

470

} catch (Exception e) {

471

System.err.println("CSV write failed: " + e.getMessage());

472

}

473

}

474

475

private List<Map<String, Object>> convertToBasicData(List<UserData> users) {

476

// Convert to simple Map structure for fallback writing

477

return users.stream()

478

.map(user -> {

479

Map<String, Object> map = new HashMap<>();

480

map.put("Name", user.getName());

481

map.put("Email", user.getEmail());

482

map.put("Age", user.getAge());

483

return map;

484

})

485

.collect(Collectors.toList());

486

}

487

}

488

```

489

490

### Custom Exception in Converters

491

```java

492

import com.alibaba.excel.converters.Converter;

493

import com.alibaba.excel.enums.CellDataTypeEnum;

494

import com.alibaba.excel.exception.ExcelDataConvertException;

495

496

public class StrictEmailConverter implements Converter<String> {

497

private static final Pattern EMAIL_PATTERN =

498

Pattern.compile("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$");

499

500

@Override

501

public Class<?> supportJavaTypeKey() {

502

return String.class;

503

}

504

505

@Override

506

public CellDataTypeEnum supportExcelTypeKey() {

507

return CellDataTypeEnum.STRING;

508

}

509

510

@Override

511

public String convertToJavaData(ReadCellData<?> cellData,

512

ExcelContentProperty contentProperty,

513

GlobalConfiguration globalConfiguration) throws Exception {

514

String email = cellData.getStringValue();

515

516

if (email == null || email.trim().isEmpty()) {

517

return null;

518

}

519

520

email = email.trim().toLowerCase();

521

522

if (!EMAIL_PATTERN.matcher(email).matches()) {

523

throw new ExcelDataConvertException(

524

"Invalid email format: " + email + ". Expected format: user@domain.com");

525

}

526

527

return email;

528

}

529

530

@Override

531

public WriteCellData<?> convertToExcelData(String value,

532

ExcelContentProperty contentProperty,

533

GlobalConfiguration globalConfiguration) throws Exception {

534

if (value != null && !EMAIL_PATTERN.matcher(value).matches()) {

535

throw new ExcelWriteDataConvertException(

536

"Invalid email format for writing: " + value);

537

}

538

539

return new WriteCellData<>(value);

540

}

541

}

542

```

543

544

### Exception Aggregation and Reporting

545

```java

546

import com.alibaba.excel.context.AnalysisContext;

547

import com.alibaba.excel.event.AnalysisEventListener;

548

import com.alibaba.excel.exception.ExcelDataConvertException;

549

550

public class ErrorReportingListener extends AnalysisEventListener<UserData> {

551

private List<UserData> validData = new ArrayList<>();

552

private List<ErrorRecord> errors = new ArrayList<>();

553

554

@Override

555

public void invoke(UserData data, AnalysisContext context) {

556

try {

557

validateAndProcess(data, context);

558

validData.add(data);

559

} catch (Exception e) {

560

recordError(e, context, data);

561

}

562

}

563

564

@Override

565

public void onException(Exception exception, AnalysisContext context) throws Exception {

566

recordError(exception, context, null);

567

// Continue processing

568

}

569

570

@Override

571

public void doAfterAllAnalysed(AnalysisContext context) {

572

generateErrorReport();

573

processValidData();

574

}

575

576

private void validateAndProcess(UserData data, AnalysisContext context) {

577

if (data.getName() == null || data.getName().trim().isEmpty()) {

578

throw new IllegalArgumentException("Name is required");

579

}

580

581

if (data.getEmail() == null || !data.getEmail().contains("@")) {

582

throw new IllegalArgumentException("Valid email is required");

583

}

584

585

if (data.getAge() != null && data.getAge() < 0) {

586

throw new IllegalArgumentException("Age cannot be negative");

587

}

588

}

589

590

private void recordError(Exception exception, AnalysisContext context, UserData data) {

591

ErrorRecord error = new ErrorRecord();

592

error.setRowNumber(context.getCurrentRowNum());

593

error.setSheetName(context.getCurrentSheet().getSheetName());

594

error.setErrorMessage(exception.getMessage());

595

error.setExceptionType(exception.getClass().getSimpleName());

596

597

if (exception instanceof ExcelDataConvertException) {

598

ExcelDataConvertException convertEx = (ExcelDataConvertException) exception;

599

error.setColumnIndex(convertEx.getColumnIndex());

600

error.setCellData(convertEx.getCellData() != null ?

601

convertEx.getCellData().toString() : null);

602

}

603

604

if (data != null) {

605

error.setRawData(data.toString());

606

}

607

608

errors.add(error);

609

}

610

611

private void generateErrorReport() {

612

System.out.println("=== Error Report ===");

613

System.out.println("Total valid records: " + validData.size());

614

System.out.println("Total errors: " + errors.size());

615

System.out.println();

616

617

if (!errors.isEmpty()) {

618

System.out.println("Error Details:");

619

for (ErrorRecord error : errors) {

620

System.out.println(String.format(

621

"Row %d%s: %s - %s",

622

error.getRowNumber(),

623

error.getColumnIndex() != null ? " Col " + error.getColumnIndex() : "",

624

error.getExceptionType(),

625

error.getErrorMessage()

626

));

627

628

if (error.getCellData() != null) {

629

System.out.println(" Cell data: " + error.getCellData());

630

}

631

if (error.getRawData() != null) {

632

System.out.println(" Raw data: " + error.getRawData());

633

}

634

System.out.println();

635

}

636

}

637

}

638

639

private void processValidData() {

640

// Process the valid data

641

System.out.println("Processing " + validData.size() + " valid records...");

642

}

643

644

// Error record class for collecting error information

645

private static class ErrorRecord {

646

private Integer rowNumber;

647

private String sheetName;

648

private Integer columnIndex;

649

private String cellData;

650

private String rawData;

651

private String errorMessage;

652

private String exceptionType;

653

654

// Getters and setters...

655

public Integer getRowNumber() { return rowNumber; }

656

public void setRowNumber(Integer rowNumber) { this.rowNumber = rowNumber; }

657

658

public String getSheetName() { return sheetName; }

659

public void setSheetName(String sheetName) { this.sheetName = sheetName; }

660

661

public Integer getColumnIndex() { return columnIndex; }

662

public void setColumnIndex(Integer columnIndex) { this.columnIndex = columnIndex; }

663

664

public String getCellData() { return cellData; }

665

public void setCellData(String cellData) { this.cellData = cellData; }

666

667

public String getRawData() { return rawData; }

668

public void setRawData(String rawData) { this.rawData = rawData; }

669

670

public String getErrorMessage() { return errorMessage; }

671

public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }

672

673

public String getExceptionType() { return exceptionType; }

674

public void setExceptionType(String exceptionType) { this.exceptionType = exceptionType; }

675

}

676

}

677

```