Browse Source

Improved logging and proper scripting initializer.

pull/802/head
Sebastian 4 years ago
parent
commit
c10b3accba
  1. 2
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs
  2. 22
      backend/src/Squidex.Infrastructure/Orleans/LoggingFilter.cs
  3. 55
      backend/src/Squidex.Web/ApiExceptionConverter.cs
  4. 6
      backend/src/Squidex.Web/ApiExceptionFilterAttribute.cs
  5. 3
      backend/src/Squidex/Config/Domain/InfrastructureServices.cs

2
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs

@ -230,7 +230,7 @@ namespace Squidex.Domain.Apps.Core.Scripting
} }
catch (Exception ex) catch (Exception ex)
{ {
throw new ValidationException(T.Get("common.jsError", new { message = ex.ToString() })); throw new ValidationException(T.Get("common.jsError", new { message = ex.GetType().Name }), ex);
} }
} }
} }

22
backend/src/Squidex.Infrastructure/Orleans/LoggingFilter.cs

@ -25,20 +25,30 @@ namespace Squidex.Infrastructure.Orleans
{ {
await context.Invoke(); await context.Invoke();
} }
catch (DomainException) catch (DomainException ex)
{ {
if (ex.InnerException != null)
{
Log(context, ex.InnerException);
}
throw; throw;
} }
catch (Exception ex) catch (Exception ex)
{ {
log.LogError(ex, w => w Log(context, ex);
.WriteProperty("action", "GrainInvoked")
.WriteProperty("status", "Failed")
.WriteProperty("grain", context.Grain.ToString())
.WriteProperty("grainMethod", context.ImplementationMethod.ToString()));
throw; throw;
} }
} }
private void Log(IIncomingGrainCallContext context, Exception ex)
{
log.LogError(ex, w => w
.WriteProperty("action", "GrainInvoked")
.WriteProperty("status", "Failed")
.WriteProperty("grain", context.Grain.ToString())
.WriteProperty("grainMethod", context.ImplementationMethod.ToString()));
}
} }
} }

55
backend/src/Squidex.Web/ApiExceptionConverter.cs

@ -33,16 +33,16 @@ namespace Squidex.Web
[500] = "https://tools.ietf.org/html/rfc7231#section-6.6.1" [500] = "https://tools.ietf.org/html/rfc7231#section-6.6.1"
}; };
public static (ErrorDto Error, bool WellKnown) ToErrorDto(int statusCode, HttpContext? httpContext) public static (ErrorDto Error, Exception? Unhandled) ToErrorDto(int statusCode, HttpContext? httpContext)
{ {
var error = new ErrorDto { StatusCode = statusCode }; var error = new ErrorDto { StatusCode = statusCode };
Enrich(httpContext, error); Enrich(httpContext, error);
return (error, true); return (error, null);
} }
public static (ErrorDto Error, bool WellKnown) ToErrorDto(this ProblemDetails problem, HttpContext? httpContext) public static (ErrorDto Error, Exception? Unhandled) ToErrorDto(this ProblemDetails problem, HttpContext? httpContext)
{ {
Guard.NotNull(problem, nameof(problem)); Guard.NotNull(problem, nameof(problem));
@ -50,10 +50,10 @@ namespace Squidex.Web
Enrich(httpContext, error); Enrich(httpContext, error);
return (error, true); return (error, null);
} }
public static (ErrorDto Error, bool WellKnown) ToErrorDto(this Exception exception, HttpContext? httpContext) public static (ErrorDto Error, Exception? Unhandled) ToErrorDto(this Exception exception, HttpContext? httpContext)
{ {
Guard.NotNull(exception, nameof(exception)); Guard.NotNull(exception, nameof(exception));
@ -76,45 +76,66 @@ namespace Squidex.Web
error.Type = Links.GetOrDefault(error.StatusCode); error.Type = Links.GetOrDefault(error.StatusCode);
} }
private static (ErrorDto Error, bool WellKnown) CreateError(Exception exception) private static (ErrorDto Error, Exception? Unhandled) CreateError(Exception exception)
{ {
switch (exception) switch (exception)
{ {
case ValidationException ex: case ValidationException ex:
return (CreateError(400, T.Get("common.httpValidationError"), null, ToErrors(ex.Errors)), true); {
var message = T.Get("common.httpValidationError");
return (CreateError(400, message, null, ToErrors(ex.Errors)), GetInner(exception));
}
case DomainObjectNotFoundException ex: case DomainObjectNotFoundException ex:
return (CreateError(404, ex.ErrorCode), true); return (CreateError(404, ex.ErrorCode), GetInner(exception));
case DomainObjectVersionException ex: case DomainObjectVersionException ex:
return (CreateError(412, ex.Message, ex.ErrorCode), true); return (CreateError(412, ex.Message, ex.ErrorCode), GetInner(exception));
case DomainObjectDeletedException ex: case DomainObjectDeletedException ex:
return (CreateError(410, ex.Message, ex.ErrorCode), true); return (CreateError(410, ex.Message, ex.ErrorCode), GetInner(exception));
case DomainObjectConflictException ex: case DomainObjectConflictException ex:
return (CreateError(409, ex.Message, ex.ErrorCode), true); return (CreateError(409, ex.Message, ex.ErrorCode), GetInner(exception));
case DomainForbiddenException ex: case DomainForbiddenException ex:
return (CreateError(403, ex.Message, ex.ErrorCode), true); return (CreateError(403, ex.Message, ex.ErrorCode), GetInner(exception));
case DomainException ex: case DomainException ex:
return (CreateError(400, ex.Message, ex.ErrorCode), true); return (CreateError(400, ex.Message, ex.ErrorCode), GetInner(exception));
case SecurityException: case SecurityException:
return (CreateError(403), false); return (CreateError(403), exception);
case DecoderFallbackException ex: case DecoderFallbackException ex:
return (CreateError(400, ex.Message), true); return (CreateError(400, ex.Message), null);
case BadHttpRequestException ex: case BadHttpRequestException ex:
return (CreateError(ex.StatusCode, ex.Message), true); return (CreateError(ex.StatusCode, ex.Message), null);
default: default:
return (CreateError(500), false); return (CreateError(500), exception);
} }
} }
private static Exception? GetInner(Exception exception)
{
var current = exception;
while (current != null)
{
if (current is not DomainException)
{
return current;
}
current = current.InnerException;
}
return null;
}
private static ErrorDto CreateError(int status, string? message = null, string? errorCode = null, IEnumerable<string>? details = null) private static ErrorDto CreateError(int status, string? message = null, string? errorCode = null, IEnumerable<string>? details = null)
{ {
var error = new ErrorDto { StatusCode = status, Message = message }; var error = new ErrorDto { StatusCode = status, Message = message };

6
backend/src/Squidex.Web/ApiExceptionFilterAttribute.cs

@ -28,13 +28,13 @@ namespace Squidex.Web
public void OnException(ExceptionContext context) public void OnException(ExceptionContext context)
{ {
var (error, wellKnown) = context.Exception.ToErrorDto(context.HttpContext); var (error, unhandled) = context.Exception.ToErrorDto(context.HttpContext);
if (!wellKnown) if (unhandled != null)
{ {
var log = context.HttpContext.RequestServices.GetRequiredService<ISemanticLog>(); var log = context.HttpContext.RequestServices.GetRequiredService<ISemanticLog>();
log.LogError(context.Exception, w => w log.LogError(unhandled, w => w
.WriteProperty("message", "An unexpected exception has occurred.")); .WriteProperty("message", "An unexpected exception has occurred."));
} }

3
backend/src/Squidex/Config/Domain/InfrastructureServices.cs

@ -72,9 +72,6 @@ namespace Squidex.Config.Domain
services.AddSingletonAs<GrainTagService>() services.AddSingletonAs<GrainTagService>()
.As<ITagService>(); .As<ITagService>();
services.AddSingletonAs<JintScriptEngine>()
.AsOptional<IScriptEngine>();
services.AddSingletonAs<CounterJintExtension>() services.AddSingletonAs<CounterJintExtension>()
.As<IJintExtension>(); .As<IJintExtension>();

Loading…
Cancel
Save