or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ai-mcp.mdconfiguration.mdcore-api.mdexceptions.mdindex.mdnaming.mdremote.md

exceptions.mddocs/

0

# Exception Handling

1

2

Comprehensive exception hierarchy with specific error codes and handling patterns for robust error management in Nacos operations. Essential for building resilient applications with proper error handling and recovery mechanisms.

3

4

## Capabilities

5

6

### NacosException

7

8

Main exception class for all Nacos operations providing structured error information with specific error codes and detailed error messages.

9

10

```java { .api }

11

/**

12

* Main exception class for Nacos operations

13

*/

14

class NacosException extends Exception {

15

/** Error code for this exception */

16

private int errCode = SERVER_ERROR;

17

18

/** Error message */

19

private String errMsg;

20

21

/** Client error codes (negative values) */

22

public static final int CLIENT_INVALID_PARAM = -400;

23

public static final int CLIENT_OVER_THRESHOLD = -503;

24

public static final int CLIENT_DISCONNECT = -401;

25

public static final int CLIENT_INVALID_SERVER_STATUS = -402;

26

public static final int CLIENT_NOT_SUPPORT = -403;

27

28

/** Server error codes (positive values) */

29

public static final int INVALID_PARAM = 400;

30

public static final int NO_RIGHT = 403;

31

public static final int NOT_FOUND = 404;

32

public static final int CONFLICT = 409;

33

public static final int SERVER_ERROR = 500;

34

public static final int BAD_GATEWAY = 502;

35

public static final int OVER_THRESHOLD = 503;

36

public static final int ASYNC_TIMEOUT = 504;

37

38

/**

39

* Default constructor with generic server error

40

*/

41

public NacosException();

42

43

/**

44

* Constructor with error code and message

45

* @param errCode Specific error code

46

* @param errMsg Error message

47

*/

48

public NacosException(int errCode, String errMsg);

49

50

/**

51

* Constructor with error code and cause

52

* @param errCode Specific error code

53

* @param throwable Underlying cause

54

*/

55

public NacosException(int errCode, Throwable throwable);

56

57

/**

58

* Constructor with error code, message, and cause

59

* @param errCode Specific error code

60

* @param errMsg Error message

61

* @param throwable Underlying cause

62

*/

63

public NacosException(int errCode, String errMsg, Throwable throwable);

64

65

/**

66

* Get error code

67

* @return Error code

68

*/

69

public int getErrCode();

70

71

/**

72

* Set error code

73

* @param errCode Error code

74

*/

75

public void setErrCode(int errCode);

76

77

/**

78

* Get error message

79

* @return Error message

80

*/

81

public String getErrMsg();

82

83

/**

84

* Set error message

85

* @param errMsg Error message

86

*/

87

public void setErrMsg(String errMsg);

88

89

/**

90

* Check if error is client-side

91

* @return true if error code is negative (client error)

92

*/

93

public boolean isClientError();

94

95

/**

96

* Check if error is server-side

97

* @return true if error code is positive (server error)

98

*/

99

public boolean isServerError();

100

101

/**

102

* Get formatted error message including error code

103

*/

104

@Override

105

public String getMessage();

106

107

/**

108

* Convert to string representation

109

*/

110

@Override

111

public String toString();

112

}

113

```

114

115

### Runtime Exceptions

116

117

Runtime exception classes for situations that don't require explicit handling but provide specific error information.

118

119

```java { .api }

120

/**

121

* Runtime exception for Nacos operations that don't require explicit handling

122

*/

123

class NacosRuntimeException extends RuntimeException {

124

/** Error code */

125

private int errorCode;

126

127

/**

128

* Default constructor

129

*/

130

public NacosRuntimeException();

131

132

/**

133

* Constructor with message

134

* @param message Error message

135

*/

136

public NacosRuntimeException(String message);

137

138

/**

139

* Constructor with message and cause

140

* @param message Error message

141

* @param cause Underlying cause

142

*/

143

public NacosRuntimeException(String message, Throwable cause);

144

145

/**

146

* Constructor with cause

147

* @param cause Underlying cause

148

*/

149

public NacosRuntimeException(Throwable cause);

150

151

/**

152

* Constructor with error code and message

153

* @param errorCode Specific error code

154

* @param message Error message

155

*/

156

public NacosRuntimeException(int errorCode, String message);

157

158

/**

159

* Constructor with error code, message, and cause

160

* @param errorCode Specific error code

161

* @param message Error message

162

* @param cause Underlying cause

163

*/

164

public NacosRuntimeException(int errorCode, String message, Throwable cause);

165

166

/**

167

* Get error code

168

* @return Error code

169

*/

170

public int getErrorCode();

171

172

/**

173

* Set error code

174

* @param errorCode Error code

175

*/

176

public void setErrorCode(int errorCode);

177

}

178

179

/**

180

* API-specific exception for invalid API usage

181

*/

182

class NacosApiException extends NacosRuntimeException {

183

/**

184

* Constructor with message

185

* @param message Error message

186

*/

187

public NacosApiException(String message);

188

189

/**

190

* Constructor with message and cause

191

* @param message Error message

192

* @param cause Underlying cause

193

*/

194

public NacosApiException(String message, Throwable cause);

195

196

/**

197

* Constructor with error code and message

198

* @param errorCode Specific error code

199

* @param message Error message

200

*/

201

public NacosApiException(int errorCode, String message);

202

}

203

```

204

205

### Serialization Exceptions

206

207

Specialized exceptions for data serialization and deserialization operations.

208

209

```java { .api }

210

/**

211

* Exception for serialization errors

212

*/

213

class NacosSerializationException extends NacosRuntimeException {

214

/**

215

* Constructor with message

216

* @param message Error message

217

*/

218

public NacosSerializationException(String message);

219

220

/**

221

* Constructor with message and cause

222

* @param message Error message

223

* @param cause Underlying cause

224

*/

225

public NacosSerializationException(String message, Throwable cause);

226

227

/**

228

* Constructor with cause

229

* @param cause Underlying cause

230

*/

231

public NacosSerializationException(Throwable cause);

232

}

233

234

/**

235

* Exception for deserialization errors

236

*/

237

class NacosDeserializationException extends NacosRuntimeException {

238

/** Target class that failed to deserialize */

239

private final Class<?> targetClass;

240

241

/**

242

* Constructor with message

243

* @param message Error message

244

*/

245

public NacosDeserializationException(String message);

246

247

/**

248

* Constructor with message and cause

249

* @param message Error message

250

* @param cause Underlying cause

251

*/

252

public NacosDeserializationException(String message, Throwable cause);

253

254

/**

255

* Constructor with target class and cause

256

* @param targetClass Class that failed to deserialize

257

* @param cause Underlying cause

258

*/

259

public NacosDeserializationException(Class<?> targetClass, Throwable cause);

260

261

/**

262

* Constructor with message, target class, and cause

263

* @param message Error message

264

* @param targetClass Class that failed to deserialize

265

* @param cause Underlying cause

266

*/

267

public NacosDeserializationException(String message, Class<?> targetClass, Throwable cause);

268

269

/**

270

* Get target class that failed to deserialize

271

* @return Target class

272

*/

273

public Class<?> getTargetClass();

274

}

275

```

276

277

### Error Code Utilities

278

279

Utility classes for working with error codes and exception classification.

280

281

```java { .api }

282

/**

283

* Utility class for error code operations

284

*/

285

class ErrorCodeUtils {

286

/**

287

* Check if error code represents a client error

288

* @param errorCode Error code to check

289

* @return true if client error (negative)

290

*/

291

public static boolean isClientError(int errorCode);

292

293

/**

294

* Check if error code represents a server error

295

* @param errorCode Error code to check

296

* @return true if server error (positive)

297

*/

298

public static boolean isServerError(int errorCode);

299

300

/**

301

* Check if error code represents a timeout

302

* @param errorCode Error code to check

303

* @return true if timeout error

304

*/

305

public static boolean isTimeoutError(int errorCode);

306

307

/**

308

* Check if error code represents a parameter validation error

309

* @param errorCode Error code to check

310

* @return true if parameter error

311

*/

312

public static boolean isParameterError(int errorCode);

313

314

/**

315

* Check if error code represents an authentication/authorization error

316

* @param errorCode Error code to check

317

* @return true if auth error

318

*/

319

public static boolean isAuthError(int errorCode);

320

321

/**

322

* Get human-readable error type description

323

* @param errorCode Error code

324

* @return Error type description

325

*/

326

public static String getErrorTypeDescription(int errorCode);

327

328

/**

329

* Create NacosException from error code

330

* @param errorCode Error code

331

* @param message Error message

332

* @return New NacosException instance

333

*/

334

public static NacosException createException(int errorCode, String message);

335

336

/**

337

* Create NacosException from error code with cause

338

* @param errorCode Error code

339

* @param message Error message

340

* @param cause Underlying cause

341

* @return New NacosException instance

342

*/

343

public static NacosException createException(int errorCode, String message, Throwable cause);

344

}

345

346

/**

347

* Exception factory for creating common Nacos exceptions

348

*/

349

class NacosExceptionFactory {

350

/**

351

* Create invalid parameter exception

352

* @param paramName Parameter name that is invalid

353

* @param paramValue Parameter value that is invalid

354

* @return NacosException for invalid parameter

355

*/

356

public static NacosException invalidParameter(String paramName, Object paramValue);

357

358

/**

359

* Create service not found exception

360

* @param serviceName Service name that was not found

361

* @return NacosException for service not found

362

*/

363

public static NacosException serviceNotFound(String serviceName);

364

365

/**

366

* Create configuration not found exception

367

* @param dataId Configuration data ID

368

* @param group Configuration group

369

* @return NacosException for configuration not found

370

*/

371

public static NacosException configNotFound(String dataId, String group);

372

373

/**

374

* Create connection timeout exception

375

* @param timeoutMs Timeout in milliseconds

376

* @return NacosException for timeout

377

*/

378

public static NacosException connectionTimeout(long timeoutMs);

379

380

/**

381

* Create server unavailable exception

382

* @param serverAddr Server address that is unavailable

383

* @return NacosException for server unavailable

384

*/

385

public static NacosException serverUnavailable(String serverAddr);

386

387

/**

388

* Create permission denied exception

389

* @param resource Resource that access was denied to

390

* @param operation Operation that was denied

391

* @return NacosException for permission denied

392

*/

393

public static NacosException permissionDenied(String resource, String operation);

394

}

395

```

396

397

## Usage Examples

398

399

### Basic Exception Handling

400

401

```java

402

import com.alibaba.nacos.api.exception.NacosException;

403

import com.alibaba.nacos.api.config.ConfigService;

404

import com.alibaba.nacos.api.naming.NamingService;

405

406

public class BasicExceptionHandling {

407

408

// Configuration operations with exception handling

409

public String getConfigSafely(ConfigService configService, String dataId, String group) {

410

try {

411

return configService.getConfig(dataId, group, 5000);

412

413

} catch (NacosException e) {

414

System.err.printf("Failed to get config %s:%s - Error %d: %s%n",

415

group, dataId, e.getErrCode(), e.getErrMsg());

416

417

// Handle specific error cases

418

switch (e.getErrCode()) {

419

case NacosException.NOT_FOUND:

420

System.out.println("Configuration not found, using default values");

421

return getDefaultConfig(dataId);

422

423

case NacosException.ASYNC_TIMEOUT:

424

System.out.println("Request timed out, retrying with longer timeout");

425

return retryGetConfig(configService, dataId, group);

426

427

case NacosException.NO_RIGHT:

428

System.err.println("Permission denied, check authentication");

429

throw new RuntimeException("Authentication required", e);

430

431

case NacosException.SERVER_ERROR:

432

System.err.println("Server error, will retry later");

433

return getCachedConfig(dataId, group);

434

435

default:

436

System.err.println("Unexpected error occurred");

437

throw new RuntimeException("Configuration retrieval failed", e);

438

}

439

}

440

}

441

442

// Service registration with comprehensive error handling

443

public boolean registerServiceSafely(NamingService namingService, String serviceName,

444

String ip, int port) {

445

try {

446

namingService.registerInstance(serviceName, ip, port);

447

System.out.printf("Successfully registered %s at %s:%d%n", serviceName, ip, port);

448

return true;

449

450

} catch (NacosException e) {

451

System.err.printf("Failed to register service %s - Error %d: %s%n",

452

serviceName, e.getErrCode(), e.getErrMsg());

453

454

if (e.isClientError()) {

455

// Client-side errors (negative error codes)

456

handleClientError(e, serviceName, ip, port);

457

} else if (e.isServerError()) {

458

// Server-side errors (positive error codes)

459

handleServerError(e, serviceName, ip, port);

460

}

461

462

return false;

463

}

464

}

465

466

private void handleClientError(NacosException e, String serviceName, String ip, int port) {

467

switch (e.getErrCode()) {

468

case NacosException.CLIENT_INVALID_PARAM:

469

System.err.printf("Invalid parameters for service registration: %s at %s:%d%n",

470

serviceName, ip, port);

471

// Validate and fix parameters

472

break;

473

474

case NacosException.CLIENT_DISCONNECT:

475

System.err.println("Client disconnected from server, attempting reconnection");

476

// Trigger reconnection logic

477

break;

478

479

case NacosException.CLIENT_OVER_THRESHOLD:

480

System.err.println("Client request rate exceeded, backing off");

481

// Implement backoff strategy

482

break;

483

484

default:

485

System.err.println("Unknown client error: " + e.getErrMsg());

486

break;

487

}

488

}

489

490

private void handleServerError(NacosException e, String serviceName, String ip, int port) {

491

switch (e.getErrCode()) {

492

case NacosException.SERVER_ERROR:

493

System.err.println("Server internal error, will retry registration");

494

// Schedule retry

495

break;

496

497

case NacosException.OVER_THRESHOLD:

498

System.err.println("Server overloaded, backing off");

499

// Implement exponential backoff

500

break;

501

502

case NacosException.BAD_GATEWAY:

503

System.err.println("Bad gateway, checking server connectivity");

504

// Check network connectivity

505

break;

506

507

default:

508

System.err.println("Unknown server error: " + e.getErrMsg());

509

break;

510

}

511

}

512

}

513

```

514

515

### Exception Classification and Recovery

516

517

```java

518

import com.alibaba.nacos.api.exception.ErrorCodeUtils;

519

import com.alibaba.nacos.api.exception.NacosExceptionFactory;

520

521

public class ExceptionClassificationExample {

522

523

// Classify exceptions for different handling strategies

524

public void handleExceptionWithClassification(NacosException e, String operation) {

525

System.out.printf("Operation '%s' failed with error %d: %s%n",

526

operation, e.getErrCode(), e.getErrMsg());

527

528

// Classify error type

529

if (ErrorCodeUtils.isTimeoutError(e.getErrCode())) {

530

handleTimeoutError(e, operation);

531

} else if (ErrorCodeUtils.isParameterError(e.getErrCode())) {

532

handleParameterError(e, operation);

533

} else if (ErrorCodeUtils.isAuthError(e.getErrCode())) {

534

handleAuthError(e, operation);

535

} else if (ErrorCodeUtils.isClientError(e.getErrCode())) {

536

handleGenericClientError(e, operation);

537

} else if (ErrorCodeUtils.isServerError(e.getErrCode())) {

538

handleGenericServerError(e, operation);

539

} else {

540

handleUnknownError(e, operation);

541

}

542

}

543

544

private void handleTimeoutError(NacosException e, String operation) {

545

System.out.println("Timeout detected, implementing retry with backoff");

546

547

// Implement exponential backoff retry

548

RetryPolicy.builder()

549

.withMaxAttempts(3)

550

.withExponentialBackoff(1000, 5000)

551

.retry(() -> retryOperation(operation));

552

}

553

554

private void handleParameterError(NacosException e, String operation) {

555

System.err.println("Parameter validation failed:");

556

System.err.println(" Error: " + ErrorCodeUtils.getErrorTypeDescription(e.getErrCode()));

557

System.err.println(" Suggestion: Check input parameters and API documentation");

558

559

// Log parameter details for debugging

560

logParameterValidationFailure(operation, e);

561

}

562

563

private void handleAuthError(NacosException e, String operation) {

564

System.err.println("Authentication/Authorization failed:");

565

System.err.println(" Check credentials and permissions");

566

567

// Attempt to refresh authentication

568

if (refreshAuthentication()) {

569

System.out.println("Authentication refreshed, retrying operation");

570

retryOperation(operation);

571

} else {

572

System.err.println("Authentication refresh failed, manual intervention required");

573

alertAdministrator("Authentication failure for operation: " + operation);

574

}

575

}

576

577

private void handleGenericClientError(NacosException e, String operation) {

578

System.err.printf("Client error %d: %s%n", e.getErrCode(), e.getErrMsg());

579

580

// Log for debugging

581

logClientError(operation, e);

582

583

// Most client errors are not recoverable automatically

584

throw new RuntimeException("Client error in operation: " + operation, e);

585

}

586

587

private void handleGenericServerError(NacosException e, String operation) {

588

System.err.printf("Server error %d: %s%n", e.getErrCode(), e.getErrMsg());

589

590

// Server errors might be transient, implement retry

591

if (isRetriableServerError(e.getErrCode())) {

592

System.out.println("Retriable server error, scheduling retry");

593

scheduleRetry(operation, calculateBackoffDelay(e.getErrCode()));

594

} else {

595

System.err.println("Non-retriable server error, alerting administrators");

596

alertAdministrator("Server error in operation: " + operation + " - " + e.getErrMsg());

597

}

598

}

599

600

private void handleUnknownError(NacosException e, String operation) {

601

System.err.printf("Unknown error %d: %s%n", e.getErrCode(), e.getErrMsg());

602

603

// Log for investigation

604

logUnknownError(operation, e);

605

606

// Conservative approach - don't retry unknown errors

607

throw new RuntimeException("Unknown error in operation: " + operation, e);

608

}

609

}

610

```

611

612

### Custom Exception Handling Framework

613

614

```java

615

import java.util.concurrent.CompletableFuture;

616

import java.util.function.Supplier;

617

import java.util.function.Function;

618

619

public class NacosExceptionHandler {

620

621

// Generic exception handling wrapper

622

public static <T> CompletableFuture<T> handleAsync(Supplier<T> operation, String operationName) {

623

return CompletableFuture.supplyAsync(() -> {

624

try {

625

return operation.get();

626

} catch (NacosException e) {

627

throw new RuntimeException(createDetailedErrorMessage(e, operationName), e);

628

}

629

});

630

}

631

632

// Exception handling with retry policy

633

public static <T> T handleWithRetry(Supplier<T> operation, String operationName,

634

int maxRetries, long delayMs) throws NacosException {

635

NacosException lastException = null;

636

637

for (int attempt = 0; attempt <= maxRetries; attempt++) {

638

try {

639

return operation.get();

640

641

} catch (NacosException e) {

642

lastException = e;

643

644

// Don't retry on certain error types

645

if (!isRetriableError(e)) {

646

throw e;

647

}

648

649

if (attempt < maxRetries) {

650

System.out.printf("Attempt %d/%d failed for %s, retrying in %dms%n",

651

attempt + 1, maxRetries + 1, operationName, delayMs);

652

653

try {

654

Thread.sleep(delayMs * (attempt + 1)); // Linear backoff

655

} catch (InterruptedException ie) {

656

Thread.currentThread().interrupt();

657

throw new NacosException(NacosException.CLIENT_DISCONNECT,

658

"Operation interrupted", ie);

659

}

660

} else {

661

System.err.printf("All %d attempts failed for %s%n",

662

maxRetries + 1, operationName);

663

}

664

}

665

}

666

667

throw lastException;

668

}

669

670

// Exception handling with circuit breaker pattern

671

public static class CircuitBreakerExceptionHandler {

672

private final AtomicInteger failureCount = new AtomicInteger(0);

673

private volatile long lastFailureTime = 0;

674

private volatile boolean circuitOpen = false;

675

676

private final int failureThreshold;

677

private final long circuitOpenTimeMs;

678

679

public CircuitBreakerExceptionHandler(int failureThreshold, long circuitOpenTimeMs) {

680

this.failureThreshold = failureThreshold;

681

this.circuitOpenTimeMs = circuitOpenTimeMs;

682

}

683

684

public <T> T execute(Supplier<T> operation, String operationName) throws NacosException {

685

// Check if circuit is open

686

if (isCircuitOpen()) {

687

throw NacosExceptionFactory.serverUnavailable(

688

"Circuit breaker is open for operation: " + operationName);

689

}

690

691

try {

692

T result = operation.get();

693

694

// Success - reset circuit

695

resetCircuit();

696

return result;

697

698

} catch (NacosException e) {

699

// Record failure

700

recordFailure();

701

702

// Check if circuit should open

703

if (shouldOpenCircuit()) {

704

openCircuit();

705

System.err.printf("Circuit breaker opened for %s after %d failures%n",

706

operationName, failureCount.get());

707

}

708

709

throw e;

710

}

711

}

712

713

private boolean isCircuitOpen() {

714

if (circuitOpen) {

715

// Check if circuit should close (half-open state)

716

if (System.currentTimeMillis() - lastFailureTime > circuitOpenTimeMs) {

717

circuitOpen = false;

718

failureCount.set(0);

719

System.out.println("Circuit breaker half-open, allowing test request");

720

}

721

}

722

723

return circuitOpen;

724

}

725

726

private void recordFailure() {

727

failureCount.incrementAndGet();

728

lastFailureTime = System.currentTimeMillis();

729

}

730

731

private boolean shouldOpenCircuit() {

732

return failureCount.get() >= failureThreshold;

733

}

734

735

private void openCircuit() {

736

circuitOpen = true;

737

}

738

739

private void resetCircuit() {

740

failureCount.set(0);

741

circuitOpen = false;

742

lastFailureTime = 0;

743

}

744

}

745

746

// Utility methods

747

private static String createDetailedErrorMessage(NacosException e, String operationName) {

748

StringBuilder sb = new StringBuilder();

749

sb.append("Operation '").append(operationName).append("' failed");

750

sb.append(" [Error ").append(e.getErrCode()).append("]: ").append(e.getErrMsg());

751

752

if (e.getCause() != null) {

753

sb.append(" (Caused by: ").append(e.getCause().getMessage()).append(")");

754

}

755

756

return sb.toString();

757

}

758

759

private static boolean isRetriableError(NacosException e) {

760

// Define which errors are retriable

761

switch (e.getErrCode()) {

762

case NacosException.ASYNC_TIMEOUT:

763

case NacosException.SERVER_ERROR:

764

case NacosException.BAD_GATEWAY:

765

case NacosException.OVER_THRESHOLD:

766

case NacosException.CLIENT_DISCONNECT:

767

return true;

768

769

case NacosException.INVALID_PARAM:

770

case NacosException.NO_RIGHT:

771

case NacosException.NOT_FOUND:

772

case NacosException.CLIENT_INVALID_PARAM:

773

return false; // Don't retry validation or auth errors

774

775

default:

776

return false; // Conservative approach for unknown errors

777

}

778

}

779

}

780

```

781

782

### Exception Monitoring and Alerting

783

784

```java

785

import java.util.concurrent.ConcurrentHashMap;

786

import java.util.concurrent.atomic.LongAdder;

787

import java.time.LocalDateTime;

788

import java.time.format.DateTimeFormatter;

789

790

public class ExceptionMonitor {

791

792

private final Map<Integer, LongAdder> errorCounts = new ConcurrentHashMap<>();

793

private final Map<String, LongAdder> operationErrorCounts = new ConcurrentHashMap<>();

794

private final List<ExceptionRecord> recentExceptions = new CopyOnWriteArrayList<>();

795

796

// Record exception occurrence

797

public void recordException(NacosException e, String operation) {

798

// Count by error code

799

errorCounts.computeIfAbsent(e.getErrCode(), k -> new LongAdder()).increment();

800

801

// Count by operation

802

String key = operation + ":" + e.getErrCode();

803

operationErrorCounts.computeIfAbsent(key, k -> new LongAdder()).increment();

804

805

// Keep recent exceptions for analysis

806

ExceptionRecord record = new ExceptionRecord(e, operation, LocalDateTime.now());

807

recentExceptions.add(record);

808

809

// Keep only last 1000 exceptions

810

while (recentExceptions.size() > 1000) {

811

recentExceptions.remove(0);

812

}

813

814

// Check for alerting conditions

815

checkAlertConditions(e, operation);

816

}

817

818

// Generate exception statistics report

819

public String generateReport() {

820

StringBuilder report = new StringBuilder();

821

report.append("=== Nacos Exception Statistics ===\n");

822

report.append("Generated at: ").append(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)).append("\n\n");

823

824

// Error code statistics

825

report.append("Error Code Counts:\n");

826

errorCounts.entrySet().stream()

827

.sorted(Map.Entry.<Integer, LongAdder>comparingByValue((a, b) -> Long.compare(b.sum(), a.sum())))

828

.forEach(entry -> {

829

int errorCode = entry.getKey();

830

long count = entry.getValue().sum();

831

String errorType = ErrorCodeUtils.getErrorTypeDescription(errorCode);

832

report.append(String.format(" %d (%s): %d occurrences%n", errorCode, errorType, count));

833

});

834

835

report.append("\nOperation Error Counts:\n");

836

operationErrorCounts.entrySet().stream()

837

.sorted(Map.Entry.<String, LongAdder>comparingByValue((a, b) -> Long.compare(b.sum(), a.sum())))

838

.limit(10) // Top 10 operation errors

839

.forEach(entry -> {

840

String operation = entry.getKey();

841

long count = entry.getValue().sum();

842

report.append(String.format(" %s: %d occurrences%n", operation, count));

843

});

844

845

// Recent critical errors

846

report.append("\nRecent Critical Errors:\n");

847

recentExceptions.stream()

848

.filter(record -> isCriticalError(record.exception.getErrCode()))

849

.sorted((a, b) -> b.timestamp.compareTo(a.timestamp))

850

.limit(5)

851

.forEach(record -> {

852

report.append(String.format(" [%s] %s - Error %d: %s%n",

853

record.timestamp.format(DateTimeFormatter.ofPattern("MM-dd HH:mm:ss")),

854

record.operation,

855

record.exception.getErrCode(),

856

record.exception.getErrMsg()));

857

});

858

859

return report.toString();

860

}

861

862

// Check for conditions that require alerts

863

private void checkAlertConditions(NacosException e, String operation) {

864

// Alert on critical errors

865

if (isCriticalError(e.getErrCode())) {

866

sendAlert(String.format("Critical Nacos error in operation %s: [%d] %s",

867

operation, e.getErrCode(), e.getErrMsg()));

868

}

869

870

// Alert on high error rates

871

String operationKey = operation + ":" + e.getErrCode();

872

long count = operationErrorCounts.get(operationKey).sum();

873

if (count > 0 && count % 10 == 0) { // Every 10th occurrence

874

sendAlert(String.format("High error rate detected: %s has occurred %d times",

875

operationKey, count));

876

}

877

878

// Alert on authentication errors

879

if (ErrorCodeUtils.isAuthError(e.getErrCode())) {

880

sendAlert(String.format("Authentication error in operation %s: %s",

881

operation, e.getErrMsg()));

882

}

883

}

884

885

private boolean isCriticalError(int errorCode) {

886

return errorCode == NacosException.SERVER_ERROR ||

887

errorCode == NacosException.NO_RIGHT ||

888

errorCode == NacosException.CLIENT_DISCONNECT;

889

}

890

891

private void sendAlert(String message) {

892

System.err.println("ALERT: " + message);

893

// Integrate with alerting system (email, Slack, etc.)

894

}

895

896

// Exception record for tracking

897

private static class ExceptionRecord {

898

final NacosException exception;

899

final String operation;

900

final LocalDateTime timestamp;

901

902

ExceptionRecord(NacosException exception, String operation, LocalDateTime timestamp) {

903

this.exception = exception;

904

this.operation = operation;

905

this.timestamp = timestamp;

906

}

907

}

908

909

// Get error rate for specific operation

910

public double getErrorRate(String operation, Duration timeWindow) {

911

LocalDateTime cutoff = LocalDateTime.now().minus(timeWindow);

912

913

long totalOperations = recentExceptions.stream()

914

.filter(record -> record.operation.equals(operation))

915

.filter(record -> record.timestamp.isAfter(cutoff))

916

.count();

917

918

if (totalOperations == 0) {

919

return 0.0;

920

}

921

922

long errorOperations = recentExceptions.stream()

923

.filter(record -> record.operation.equals(operation))

924

.filter(record -> record.timestamp.isAfter(cutoff))

925

.filter(record -> record.exception != null)

926

.count();

927

928

return (double) errorOperations / totalOperations;

929

}

930

931

// Reset statistics

932

public void reset() {

933

errorCounts.clear();

934

operationErrorCounts.clear();

935

recentExceptions.clear();

936

}

937

}