All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.zodiac.reactor.exception.TraceSourceException Maven / Gradle / Ivy

The newest version!
package org.zodiac.reactor.exception;

import reactor.core.publisher.Mono;
import reactor.util.context.Context;

import javax.annotation.Nullable;

import org.springframework.context.MessageSource;
import org.springframework.util.StringUtils;
import org.zodiac.reactor.util.SpringLocaleUtil;

import java.util.Locale;
import java.util.function.Function;

/**
 * Support traceability of exceptions, and identify the source of exceptions through {@link TraceSourceException#withSource(Object) }.
* Handle some logic by getting the source of the exception where the exception is caught.
* For example: to determine which piece of data the error occurred, etc. */ public class TraceSourceException extends RuntimeException { private static final long serialVersionUID = -4042507425502136519L; private static final String DEEP_TRACE_KEY = TraceSourceException.class.getName() + "_deep"; private static final Context DEEP_TRACE_CONTEXT = Context.of(DEEP_TRACE_KEY, true); private String operation; private Object source; public TraceSourceException() { } public TraceSourceException(String message) { super(message); } public TraceSourceException(Throwable e) { super(e.getMessage(),e); } public TraceSourceException(String message, Throwable e) { super(message, e); } @Nullable public Object getSource() { return source; } @Nullable public String getOperation() { return operation; } public TraceSourceException withSource(Object source) { this.source = source; return self(); } public TraceSourceException withSource(String operation, Object source) { this.operation = operation; this.source = source; return self(); } protected TraceSourceException self() { return this; } /** * The deep traceability context is used to identify whether it is a deep traceability exception. When depth tracking is enabled, a new {@link TraceSourceException} object is created. * * @return The {@link Context}. * @see reactor.core.publisher.Flux#subscriberContext(Context) * @see Mono#subscriberContext(Context) */ public static Context deepTraceContext() { return DEEP_TRACE_CONTEXT; } public static Function> transfer(Object source) { return transfer(null, source); } /** * Tracing the origin of the anomaly converter. Usually used in conjunction with {@link Mono#onErrorResume(Function)}. *
* Conversion logic: *
    *
  1. If the captured exception is not {@link TraceSourceException}, a new {@link TraceSourceException} is created directly and returned.
  2. *
  3. *
    *
      *
    • If the catched exception is {@link TraceSourceException} and the context does not specify {@link TraceSourceException#deepTraceContext()}, modify the source in the catched {@link TraceSourceException}.
    • *
    • If {@link TraceSourceException#deepTraceContext()} is specified in the context, a new {@link TraceSourceException} is created.
    • *
    *
    *
*
* *
{@code
     *
     *  doSomething()
     *  .onErrorResume(TraceSourceException.transfer(data))
     *
     * }
* * @param operation The name of the operation. * @param source The source * @param The result type. * @return Converter. * @see reactor.core.publisher.Flux#onErrorResume(Function) * @see Mono#onErrorResume(Function) */ public static Function> transfer(String operation, Object source) { if (source == null && operation == null) { return Mono::error; } return err -> { if (err instanceof TraceSourceException) { return Mono .deferWithContext(ctx -> { if (ctx.hasKey(DEEP_TRACE_KEY)) { return Mono.error(new TraceSourceException(err).withSource(operation,source)); } else { return Mono.error(((TraceSourceException) err).withSource(operation,source)); } }); } return Mono.error(new TraceSourceException(err).withSource(operation,source)); }; } public static Object tryGetSource(Throwable err) { if (err instanceof TraceSourceException) { return ((TraceSourceException) err).getSource(); } return null; } public static String tryGetOperation(Throwable err) { if (err instanceof TraceSourceException) { return ((TraceSourceException) err).getOperation(); } return null; } public static String tryGetOperationLocalized(Throwable err, MessageSource messageSource, Locale locale) { String opt = tryGetOperation(err); return StringUtils.hasText(opt) ? SpringLocaleUtil.resolveMessage(messageSource, locale, opt, opt) : opt; } public static Mono tryGetOperationLocalizedReactive(Throwable err, MessageSource messageSource) { return SpringLocaleUtil .currentReactive() .handle((locale, sink) -> { String opt = tryGetOperationLocalized(err, messageSource, locale); if (opt != null) { sink.next(opt); } }); } public static String tryGetOperationLocalized(Throwable err, Locale locale) { String opt = tryGetOperation(err); return StringUtils.hasText(opt) ? SpringLocaleUtil.resolveMessage(opt, locale, opt) : opt; } public static Mono tryGetOperationLocalizedReactive(Throwable err) { return SpringLocaleUtil .currentReactive() .handle((locale, sink) -> { String opt = tryGetOperationLocalized(err, locale); if (opt != null) { sink.next(opt); } }); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy