mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-13 02:28:10 +00:00
Don’t validate error codes on client side (#3131)
* Don’t validate error codes on client side * Update docs * Format * Format * Format
This commit is contained in:
@ -1109,7 +1109,8 @@ If webhook is set to have Event Grid message format then the payload will look a
|
|||||||
"code": 468,
|
"code": 468,
|
||||||
"errors": [
|
"errors": [
|
||||||
"example error message"
|
"example error message"
|
||||||
]
|
],
|
||||||
|
"title": "TASK_FAILED"
|
||||||
},
|
},
|
||||||
"task_id": "00000000-0000-0000-0000-000000000000",
|
"task_id": "00000000-0000-0000-0000-000000000000",
|
||||||
"task_type": "libfuzzer_fuzz"
|
"task_type": "libfuzzer_fuzz"
|
||||||
@ -1130,7 +1131,8 @@ If webhook is set to have Event Grid message format then the payload will look a
|
|||||||
"Error": {
|
"Error": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"code": {
|
"code": {
|
||||||
"$ref": "#/definitions/ErrorCode"
|
"title": "Code",
|
||||||
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"items": {
|
"items": {
|
||||||
@ -1138,56 +1140,20 @@ If webhook is set to have Event Grid message format then the payload will look a
|
|||||||
},
|
},
|
||||||
"title": "Errors",
|
"title": "Errors",
|
||||||
"type": "array"
|
"type": "array"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"title": "Title",
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"code",
|
"code",
|
||||||
|
"title",
|
||||||
"errors"
|
"errors"
|
||||||
],
|
],
|
||||||
"title": "Error",
|
"title": "Error",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"ErrorCode": {
|
|
||||||
"description": "An enumeration.",
|
|
||||||
"enum": [
|
|
||||||
450,
|
|
||||||
451,
|
|
||||||
452,
|
|
||||||
453,
|
|
||||||
454,
|
|
||||||
455,
|
|
||||||
456,
|
|
||||||
457,
|
|
||||||
458,
|
|
||||||
459,
|
|
||||||
460,
|
|
||||||
461,
|
|
||||||
462,
|
|
||||||
463,
|
|
||||||
464,
|
|
||||||
465,
|
|
||||||
467,
|
|
||||||
468,
|
|
||||||
469,
|
|
||||||
470,
|
|
||||||
471,
|
|
||||||
472,
|
|
||||||
473,
|
|
||||||
474,
|
|
||||||
475,
|
|
||||||
476,
|
|
||||||
477,
|
|
||||||
478,
|
|
||||||
479,
|
|
||||||
480,
|
|
||||||
481,
|
|
||||||
482,
|
|
||||||
483,
|
|
||||||
484,
|
|
||||||
485
|
|
||||||
],
|
|
||||||
"title": "ErrorCode"
|
|
||||||
},
|
|
||||||
"JobConfig": {
|
"JobConfig": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"build": {
|
"build": {
|
||||||
@ -1762,7 +1728,8 @@ If webhook is set to have Event Grid message format then the payload will look a
|
|||||||
"code": 472,
|
"code": 472,
|
||||||
"errors": [
|
"errors": [
|
||||||
"example error message"
|
"example error message"
|
||||||
]
|
],
|
||||||
|
"title": "PROXY_FAILED"
|
||||||
},
|
},
|
||||||
"proxy_id": "00000000-0000-0000-0000-000000000000",
|
"proxy_id": "00000000-0000-0000-0000-000000000000",
|
||||||
"region": "eastus"
|
"region": "eastus"
|
||||||
@ -1777,7 +1744,8 @@ If webhook is set to have Event Grid message format then the payload will look a
|
|||||||
"Error": {
|
"Error": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"code": {
|
"code": {
|
||||||
"$ref": "#/definitions/ErrorCode"
|
"title": "Code",
|
||||||
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"items": {
|
"items": {
|
||||||
@ -1785,55 +1753,19 @@ If webhook is set to have Event Grid message format then the payload will look a
|
|||||||
},
|
},
|
||||||
"title": "Errors",
|
"title": "Errors",
|
||||||
"type": "array"
|
"type": "array"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"title": "Title",
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"code",
|
"code",
|
||||||
|
"title",
|
||||||
"errors"
|
"errors"
|
||||||
],
|
],
|
||||||
"title": "Error",
|
"title": "Error",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
|
||||||
"ErrorCode": {
|
|
||||||
"description": "An enumeration.",
|
|
||||||
"enum": [
|
|
||||||
450,
|
|
||||||
451,
|
|
||||||
452,
|
|
||||||
453,
|
|
||||||
454,
|
|
||||||
455,
|
|
||||||
456,
|
|
||||||
457,
|
|
||||||
458,
|
|
||||||
459,
|
|
||||||
460,
|
|
||||||
461,
|
|
||||||
462,
|
|
||||||
463,
|
|
||||||
464,
|
|
||||||
465,
|
|
||||||
467,
|
|
||||||
468,
|
|
||||||
469,
|
|
||||||
470,
|
|
||||||
471,
|
|
||||||
472,
|
|
||||||
473,
|
|
||||||
474,
|
|
||||||
475,
|
|
||||||
476,
|
|
||||||
477,
|
|
||||||
478,
|
|
||||||
479,
|
|
||||||
480,
|
|
||||||
481,
|
|
||||||
482,
|
|
||||||
483,
|
|
||||||
484,
|
|
||||||
485
|
|
||||||
],
|
|
||||||
"title": "ErrorCode"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -2708,7 +2640,8 @@ If webhook is set to have Event Grid message format then the payload will look a
|
|||||||
"code": 456,
|
"code": 456,
|
||||||
"errors": [
|
"errors": [
|
||||||
"example error message"
|
"example error message"
|
||||||
]
|
],
|
||||||
|
"title": "UNABLE_TO_RESIZE"
|
||||||
},
|
},
|
||||||
"pool_name": "example",
|
"pool_name": "example",
|
||||||
"scaleset_id": "example-000"
|
"scaleset_id": "example-000"
|
||||||
@ -2723,7 +2656,8 @@ If webhook is set to have Event Grid message format then the payload will look a
|
|||||||
"Error": {
|
"Error": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"code": {
|
"code": {
|
||||||
"$ref": "#/definitions/ErrorCode"
|
"title": "Code",
|
||||||
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"items": {
|
"items": {
|
||||||
@ -2731,55 +2665,19 @@ If webhook is set to have Event Grid message format then the payload will look a
|
|||||||
},
|
},
|
||||||
"title": "Errors",
|
"title": "Errors",
|
||||||
"type": "array"
|
"type": "array"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"title": "Title",
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"code",
|
"code",
|
||||||
|
"title",
|
||||||
"errors"
|
"errors"
|
||||||
],
|
],
|
||||||
"title": "Error",
|
"title": "Error",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
|
||||||
"ErrorCode": {
|
|
||||||
"description": "An enumeration.",
|
|
||||||
"enum": [
|
|
||||||
450,
|
|
||||||
451,
|
|
||||||
452,
|
|
||||||
453,
|
|
||||||
454,
|
|
||||||
455,
|
|
||||||
456,
|
|
||||||
457,
|
|
||||||
458,
|
|
||||||
459,
|
|
||||||
460,
|
|
||||||
461,
|
|
||||||
462,
|
|
||||||
463,
|
|
||||||
464,
|
|
||||||
465,
|
|
||||||
467,
|
|
||||||
468,
|
|
||||||
469,
|
|
||||||
470,
|
|
||||||
471,
|
|
||||||
472,
|
|
||||||
473,
|
|
||||||
474,
|
|
||||||
475,
|
|
||||||
476,
|
|
||||||
477,
|
|
||||||
478,
|
|
||||||
479,
|
|
||||||
480,
|
|
||||||
481,
|
|
||||||
482,
|
|
||||||
483,
|
|
||||||
484,
|
|
||||||
485
|
|
||||||
],
|
|
||||||
"title": "ErrorCode"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -3411,7 +3309,8 @@ If webhook is set to have Event Grid message format then the payload will look a
|
|||||||
"code": 468,
|
"code": 468,
|
||||||
"errors": [
|
"errors": [
|
||||||
"example error message"
|
"example error message"
|
||||||
]
|
],
|
||||||
|
"title": "TASK_FAILED"
|
||||||
},
|
},
|
||||||
"job_id": "00000000-0000-0000-0000-000000000000",
|
"job_id": "00000000-0000-0000-0000-000000000000",
|
||||||
"task_id": "00000000-0000-0000-0000-000000000000",
|
"task_id": "00000000-0000-0000-0000-000000000000",
|
||||||
@ -3451,7 +3350,8 @@ If webhook is set to have Event Grid message format then the payload will look a
|
|||||||
"Error": {
|
"Error": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"code": {
|
"code": {
|
||||||
"$ref": "#/definitions/ErrorCode"
|
"title": "Code",
|
||||||
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"items": {
|
"items": {
|
||||||
@ -3459,56 +3359,20 @@ If webhook is set to have Event Grid message format then the payload will look a
|
|||||||
},
|
},
|
||||||
"title": "Errors",
|
"title": "Errors",
|
||||||
"type": "array"
|
"type": "array"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"title": "Title",
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"code",
|
"code",
|
||||||
|
"title",
|
||||||
"errors"
|
"errors"
|
||||||
],
|
],
|
||||||
"title": "Error",
|
"title": "Error",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"ErrorCode": {
|
|
||||||
"description": "An enumeration.",
|
|
||||||
"enum": [
|
|
||||||
450,
|
|
||||||
451,
|
|
||||||
452,
|
|
||||||
453,
|
|
||||||
454,
|
|
||||||
455,
|
|
||||||
456,
|
|
||||||
457,
|
|
||||||
458,
|
|
||||||
459,
|
|
||||||
460,
|
|
||||||
461,
|
|
||||||
462,
|
|
||||||
463,
|
|
||||||
464,
|
|
||||||
465,
|
|
||||||
467,
|
|
||||||
468,
|
|
||||||
469,
|
|
||||||
470,
|
|
||||||
471,
|
|
||||||
472,
|
|
||||||
473,
|
|
||||||
474,
|
|
||||||
475,
|
|
||||||
476,
|
|
||||||
477,
|
|
||||||
478,
|
|
||||||
479,
|
|
||||||
480,
|
|
||||||
481,
|
|
||||||
482,
|
|
||||||
483,
|
|
||||||
484,
|
|
||||||
485
|
|
||||||
],
|
|
||||||
"title": "ErrorCode"
|
|
||||||
},
|
|
||||||
"StatsFormat": {
|
"StatsFormat": {
|
||||||
"description": "An enumeration.",
|
"description": "An enumeration.",
|
||||||
"enum": [
|
"enum": [
|
||||||
@ -5530,7 +5394,8 @@ If webhook is set to have Event Grid message format then the payload will look a
|
|||||||
"Error": {
|
"Error": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"code": {
|
"code": {
|
||||||
"$ref": "#/definitions/ErrorCode"
|
"title": "Code",
|
||||||
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"items": {
|
"items": {
|
||||||
@ -5538,56 +5403,20 @@ If webhook is set to have Event Grid message format then the payload will look a
|
|||||||
},
|
},
|
||||||
"title": "Errors",
|
"title": "Errors",
|
||||||
"type": "array"
|
"type": "array"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"title": "Title",
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"code",
|
"code",
|
||||||
|
"title",
|
||||||
"errors"
|
"errors"
|
||||||
],
|
],
|
||||||
"title": "Error",
|
"title": "Error",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"ErrorCode": {
|
|
||||||
"description": "An enumeration.",
|
|
||||||
"enum": [
|
|
||||||
450,
|
|
||||||
451,
|
|
||||||
452,
|
|
||||||
453,
|
|
||||||
454,
|
|
||||||
455,
|
|
||||||
456,
|
|
||||||
457,
|
|
||||||
458,
|
|
||||||
459,
|
|
||||||
460,
|
|
||||||
461,
|
|
||||||
462,
|
|
||||||
463,
|
|
||||||
464,
|
|
||||||
465,
|
|
||||||
467,
|
|
||||||
468,
|
|
||||||
469,
|
|
||||||
470,
|
|
||||||
471,
|
|
||||||
472,
|
|
||||||
473,
|
|
||||||
474,
|
|
||||||
475,
|
|
||||||
476,
|
|
||||||
477,
|
|
||||||
478,
|
|
||||||
479,
|
|
||||||
480,
|
|
||||||
481,
|
|
||||||
482,
|
|
||||||
483,
|
|
||||||
484,
|
|
||||||
485
|
|
||||||
],
|
|
||||||
"title": "ErrorCode"
|
|
||||||
},
|
|
||||||
"EventCrashReported": {
|
"EventCrashReported": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"container": {
|
"container": {
|
||||||
|
@ -168,11 +168,17 @@ public record Proxy
|
|||||||
) : StatefulEntityBase<VmState>(State);
|
) : StatefulEntityBase<VmState>(State);
|
||||||
|
|
||||||
public record Error(ErrorCode Code, List<string>? Errors) {
|
public record Error(ErrorCode Code, List<string>? Errors) {
|
||||||
public static Error Create(ErrorCode code, params string[] errors) {
|
// A human-readable version of the ErrorCode,
|
||||||
return new Error(code, errors.ToList());
|
// so that when serialized to JSON there is something useful,
|
||||||
}
|
// not just a number. This is named 'Title' to align with the
|
||||||
|
// ProblemDetails class.
|
||||||
|
public string Title => Code.ToString();
|
||||||
|
|
||||||
|
public static Error Create(ErrorCode code, params string[] errors)
|
||||||
|
=> new(code, errors.ToList());
|
||||||
|
|
||||||
public sealed override string ToString() {
|
public sealed override string ToString() {
|
||||||
var errorsString = Errors != null ? string.Join("", Errors) : string.Empty;
|
var errorsString = Errors != null ? string.Concat("; ", Errors) : string.Empty;
|
||||||
return $"Error {{ Code = {Code}, Errors = {errorsString} }}";
|
return $"Error {{ Code = {Code}, Errors = {errorsString} }}";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
15
src/ApiService/Tests/ErrorTests.cs
Normal file
15
src/ApiService/Tests/ErrorTests.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using Microsoft.OneFuzz.Service;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Tests;
|
||||||
|
|
||||||
|
public class ErrorTests {
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void JsonHasErrorTitle() {
|
||||||
|
var error = Error.Create(ErrorCode.INVALID_IMAGE);
|
||||||
|
var json = JsonSerializer.Serialize(error);
|
||||||
|
Assert.Equal(@"{""Code"":463,""Errors"":[],""Title"":""INVALID_IMAGE""}", json);
|
||||||
|
}
|
||||||
|
}
|
@ -7,9 +7,9 @@ namespace Tests;
|
|||||||
public class EventTests {
|
public class EventTests {
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
static void CheckAllEventClass() {
|
public static void CheckAllEventClass() {
|
||||||
// instantiate one event to force the static constructor to run
|
// instantiate one event to force the static constructor to run
|
||||||
var testEvent = new EventPing(Guid.Empty);
|
// if it doesn't throw then this test passes
|
||||||
|
_ = new EventPing(Guid.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,11 @@ def main() -> None:
|
|||||||
EventTaskFailed(
|
EventTaskFailed(
|
||||||
job_id=UUID(int=0),
|
job_id=UUID(int=0),
|
||||||
task_id=UUID(int=0),
|
task_id=UUID(int=0),
|
||||||
error=Error(code=ErrorCode.TASK_FAILED, errors=["example error message"]),
|
error=Error(
|
||||||
|
code=ErrorCode.TASK_FAILED.value,
|
||||||
|
title="TASK_FAILED",
|
||||||
|
errors=["example error message"],
|
||||||
|
),
|
||||||
user_info=UserInfo(
|
user_info=UserInfo(
|
||||||
application_id=UUID(int=0),
|
application_id=UUID(int=0),
|
||||||
object_id=UUID(int=0),
|
object_id=UUID(int=0),
|
||||||
@ -171,7 +175,11 @@ def main() -> None:
|
|||||||
EventProxyFailed(
|
EventProxyFailed(
|
||||||
region=Region("eastus"),
|
region=Region("eastus"),
|
||||||
proxy_id=UUID(int=0),
|
proxy_id=UUID(int=0),
|
||||||
error=Error(code=ErrorCode.PROXY_FAILED, errors=["example error message"]),
|
error=Error(
|
||||||
|
code=ErrorCode.PROXY_FAILED.value,
|
||||||
|
title="PROXY_FAILED",
|
||||||
|
errors=["example error message"],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
EventProxyStateUpdated(
|
EventProxyStateUpdated(
|
||||||
region=Region("eastus"),
|
region=Region("eastus"),
|
||||||
@ -197,7 +205,9 @@ def main() -> None:
|
|||||||
scaleset_id="example-000",
|
scaleset_id="example-000",
|
||||||
pool_name=PoolName("example"),
|
pool_name=PoolName("example"),
|
||||||
error=Error(
|
error=Error(
|
||||||
code=ErrorCode.UNABLE_TO_RESIZE, errors=["example error message"]
|
code=ErrorCode.UNABLE_TO_RESIZE.value,
|
||||||
|
title="UNABLE_TO_RESIZE",
|
||||||
|
errors=["example error message"],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
EventScalesetDeleted(scaleset_id="example-000", pool_name=PoolName("example")),
|
EventScalesetDeleted(scaleset_id="example-000", pool_name=PoolName("example")),
|
||||||
@ -231,7 +241,9 @@ def main() -> None:
|
|||||||
task_id=UUID(int=0),
|
task_id=UUID(int=0),
|
||||||
task_type=TaskType.libfuzzer_fuzz,
|
task_type=TaskType.libfuzzer_fuzz,
|
||||||
error=Error(
|
error=Error(
|
||||||
code=ErrorCode.TASK_FAILED, errors=["example error message"]
|
code=ErrorCode.TASK_FAILED.value,
|
||||||
|
title="TASK_FAILED",
|
||||||
|
errors=["example error message"],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
JobTaskStopped(
|
JobTaskStopped(
|
||||||
|
@ -18,7 +18,6 @@ from .enums import (
|
|||||||
Compare,
|
Compare,
|
||||||
ContainerPermission,
|
ContainerPermission,
|
||||||
ContainerType,
|
ContainerType,
|
||||||
ErrorCode,
|
|
||||||
GithubIssueSearchMatch,
|
GithubIssueSearchMatch,
|
||||||
GithubIssueState,
|
GithubIssueState,
|
||||||
HeartbeatType,
|
HeartbeatType,
|
||||||
@ -95,7 +94,11 @@ class EnumModel(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class Error(BaseModel):
|
class Error(BaseModel):
|
||||||
code: ErrorCode
|
# the code here is from ErrorCodes.cs, but we don't
|
||||||
|
# want to validate the error code on the client-side
|
||||||
|
code: int
|
||||||
|
# a human-readable version of the error code
|
||||||
|
title: str
|
||||||
errors: List[str]
|
errors: List[str]
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user