Skip to content

Commit

Permalink
improve error reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
qmuntal committed Oct 13, 2021
1 parent eb4857f commit 207a8cb
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 196 deletions.
22 changes: 11 additions & 11 deletions beamlattice/decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,17 @@ func TestDecode(t *testing.T) {

func TestDecode_warns(t *testing.T) {
want := []string{
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice: %v", errors.NewParseAttrError("radius", true)),
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice: %v", errors.NewParseAttrError("minlength", true)),
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice: %v", errors.NewParseAttrError("cap", false)),
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice: %v", errors.NewParseAttrError("clippingmode", false)),
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice: %v", errors.NewParseAttrError("clippingmesh", false)),
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice: %v", errors.NewParseAttrError("representationmesh", false)),
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice/beams/beam[0]: %v", errors.NewParseAttrError("r1", false)),
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice/beams/beam[0]: %v", errors.NewParseAttrError("r2", false)),
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice/beams/beam[2]: %v", errors.NewParseAttrError("v2", true)),
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice/beams/beam[3]: %v", errors.NewParseAttrError("v1", true)),
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice/beamsets/beamset[0]/ref[2]: %v", errors.NewParseAttrError("index", true)),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice: %v", errors.NewParseAttrError("radius", true)),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice: %v", errors.NewParseAttrError("minlength", true)),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice: %v", errors.NewParseAttrError("cap", false)),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice: %v", errors.NewParseAttrError("clippingmode", false)),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice: %v", errors.NewParseAttrError("clippingmesh", false)),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice: %v", errors.NewParseAttrError("representationmesh", false)),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice/beams/beam[0]: %v", errors.NewParseAttrError("r1", false)),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice/beams/beam[0]: %v", errors.NewParseAttrError("r2", false)),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice/beams/beam[2]: %v", errors.NewParseAttrError("v2", true)),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice/beams/beam[3]: %v", errors.NewParseAttrError("v1", true)),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice/beamsets/beamset[0]/ref[2]: %v", errors.NewParseAttrError("index", true)),
}
got := new(go3mf.Model)
got.Path = "/3D/3dmodel.model"
Expand Down
36 changes: 18 additions & 18 deletions beamlattice/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,21 @@ func TestValidate(t *testing.T) {
{ID: 1, Mesh: &go3mf.Mesh{Any: spec.Any{&BeamLattice{}}}},
}}},
}}, []string{
fmt.Sprintf("/other.model/model/resources/object[0]/mesh: %v", errors.ErrInsufficientVertices),
fmt.Sprintf("/other.model/model/resources/object[0]/mesh/beamlattice: %v", &errors.MissingFieldError{Name: attrMinLength}),
fmt.Sprintf("/other.model/model/resources/object[0]/mesh/beamlattice: %v", &errors.MissingFieldError{Name: attrRadius}),
fmt.Sprintf("/other.model/model/resources/object[0]/mesh/beamlattice: %v", ErrLatticeClippedNoMesh),
fmt.Sprintf("go3mf: Path: /other.model XPath: /model/resources/object[0]/mesh: %v", errors.ErrInsufficientVertices),
fmt.Sprintf("go3mf: Path: /other.model XPath: /model/resources/object[0]/mesh/beamlattice: %v", &errors.MissingFieldError{Name: attrMinLength}),
fmt.Sprintf("go3mf: Path: /other.model XPath: /model/resources/object[0]/mesh/beamlattice: %v", &errors.MissingFieldError{Name: attrRadius}),
fmt.Sprintf("go3mf: Path: /other.model XPath: /model/resources/object[0]/mesh/beamlattice: %v", ErrLatticeClippedNoMesh),
}},
{"object without beamlattice", &go3mf.Model{Resources: go3mf.Resources{Objects: []*go3mf.Object{
{ID: 1, Mesh: &go3mf.Mesh{}},
}}}, []string{
fmt.Sprintf("model/resources/object[0]/mesh: %v", errors.ErrInsufficientVertices),
fmt.Sprintf("model/resources/object[0]/mesh: %v", errors.ErrInsufficientTriangles),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh: %v", errors.ErrInsufficientVertices),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh: %v", errors.ErrInsufficientTriangles),
}},
{"object with components", &go3mf.Model{Resources: go3mf.Resources{Objects: []*go3mf.Object{
{ID: 1, Components: &go3mf.Components{Component: []*go3mf.Component{{ObjectID: 2}}}},
}}}, []string{
fmt.Sprintf("model/resources/object[0]/components/component[0]: %v", errors.ErrMissingResource),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/components/component[0]: %v", errors.ErrMissingResource),
}},
{"object incorret type", &go3mf.Model{Resources: go3mf.Resources{Objects: []*go3mf.Object{
{ID: 1, Type: go3mf.ObjectTypeOther, Mesh: &go3mf.Mesh{Any: spec.Any{&BeamLattice{
Expand All @@ -51,9 +51,9 @@ func TestValidate(t *testing.T) {
MinLength: 1, Radius: 1, ClipMode: ClipInside,
}}}},
}}}, []string{
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice: %v", ErrLatticeObjType),
fmt.Sprintf("model/resources/object[1]/mesh/beamlattice: %v", ErrLatticeObjType),
fmt.Sprintf("model/resources/object[2]/mesh/beamlattice: %v", ErrLatticeObjType),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice: %v", ErrLatticeObjType),
fmt.Sprintf("go3mf: XPath: /model/resources/object[1]/mesh/beamlattice: %v", ErrLatticeObjType),
fmt.Sprintf("go3mf: XPath: /model/resources/object[2]/mesh/beamlattice: %v", ErrLatticeObjType),
}},
{"incorrect mesh references", &go3mf.Model{Resources: go3mf.Resources{Objects: []*go3mf.Object{
{ID: 1, Mesh: &go3mf.Mesh{Vertices: go3mf.Vertices{Vertex: []go3mf.Point3D{{}, {}, {}}}, Any: spec.Any{nil}}},
Expand All @@ -64,9 +64,9 @@ func TestValidate(t *testing.T) {
MinLength: 1, Radius: 1, ClippingMeshID: 1, RepresentationMeshID: 2,
}}}},
}}}, []string{
fmt.Sprintf("model/resources/object[1]/mesh/beamlattice: %v", errors.ErrMissingResource),
fmt.Sprintf("model/resources/object[1]/mesh/beamlattice: %v", errors.ErrRecursion),
fmt.Sprintf("model/resources/object[2]/mesh/beamlattice: %v", ErrLatticeInvalidMesh),
fmt.Sprintf("go3mf: XPath: /model/resources/object[1]/mesh/beamlattice: %v", errors.ErrMissingResource),
fmt.Sprintf("go3mf: XPath: /model/resources/object[1]/mesh/beamlattice: %v", errors.ErrRecursion),
fmt.Sprintf("go3mf: XPath: /model/resources/object[2]/mesh/beamlattice: %v", ErrLatticeInvalidMesh),
}},
{"incorrect beams", &go3mf.Model{Resources: go3mf.Resources{Objects: []*go3mf.Object{
{ID: 2, Mesh: &go3mf.Mesh{Vertices: go3mf.Vertices{Vertex: []go3mf.Point3D{{}, {}, {}}}, Any: spec.Any{&BeamLattice{
Expand All @@ -75,10 +75,10 @@ func TestValidate(t *testing.T) {
},
}}}}},
}}}, []string{
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice/beam[0]: %v", ErrLatticeSameVertex),
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice/beam[1]: %v", ErrLatticeSameVertex),
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice/beam[1]: %v", ErrLatticeBeamR2),
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice/beam[2]: %v", errors.ErrIndexOutOfBounds),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice/beam[0]: %v", ErrLatticeSameVertex),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice/beam[1]: %v", ErrLatticeSameVertex),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice/beam[1]: %v", ErrLatticeBeamR2),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice/beam[2]: %v", errors.ErrIndexOutOfBounds),
}},
{"incorrect beamseat", &go3mf.Model{Resources: go3mf.Resources{Objects: []*go3mf.Object{
{ID: 2, Mesh: &go3mf.Mesh{Vertices: go3mf.Vertices{Vertex: []go3mf.Point3D{{}, {}, {}}}, Any: spec.Any{&BeamLattice{
Expand All @@ -87,7 +87,7 @@ func TestValidate(t *testing.T) {
}}, BeamSets: BeamSets{BeamSet: []BeamSet{{Refs: []uint32{0, 2, 3}}}},
}}}},
}}}, []string{
fmt.Sprintf("model/resources/object[0]/mesh/beamlattice/beamset[0]: %v", errors.ErrIndexOutOfBounds),
fmt.Sprintf("go3mf: XPath: /model/resources/object[0]/mesh/beamlattice/beamset[0]: %v", errors.ErrIndexOutOfBounds),
}},
}
for _, tt := range tests {
Expand Down
15 changes: 9 additions & 6 deletions errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,19 @@ func (e *Error) Unwrap() error {
return e.Err
}

func (e *Error) Error() string {
levels := make([]string, len(e.Target)+1)
levels[0] = e.Path
func (e *Error) XPath() string {
levels := make([]string, len(e.Target))
for i, l := range e.Target {
levels[len(e.Target)-i] = l.String()
levels[len(e.Target)-i-1] = l.String()
}
return "/" + strings.Join(levels, "/")
}

func (e *Error) Error() string {
if e.Path == "" {
levels = levels[1:]
return fmt.Sprintf("go3mf: XPath: %s: %v", e.XPath(), e.Err)
}
return fmt.Sprintf("%s: %v", strings.Join(levels, "/"), e.Err)
return fmt.Sprintf("go3mf: Path: %s XPath: %s: %v", e.Path, e.XPath(), e.Err)
}

func NewMissingFieldError(name string) error {
Expand Down
16 changes: 8 additions & 8 deletions materials/decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ func TestDecode(t *testing.T) {

func TestDecode_warns(t *testing.T) {
want := []string{
fmt.Sprintf("model/resources/texture2d[1]: %v", errors.NewParseAttrError("id", true)),
fmt.Sprintf("model/resources/colorgroup[2]/color[0]: %v", errors.NewParseAttrError("color", true)),
fmt.Sprintf("model/resources/texture2dgroup[3]: %v", errors.NewParseAttrError("texid", true)),
fmt.Sprintf("model/resources/texture2dgroup[3]/tex2coord[0]: %v", errors.NewParseAttrError("u", true)),
fmt.Sprintf("model/resources/texture2dgroup[3]/tex2coord[1]: %v", errors.NewParseAttrError("v", true)),
fmt.Sprintf("model/resources/compositematerials[4]: %v", errors.NewParseAttrError("matid", true)),
fmt.Sprintf("model/resources/compositematerials[4]/composite[1]: %v", errors.NewParseAttrError("values", true)),
fmt.Sprintf("model/resources/multiproperties[5]: %v", errors.NewParseAttrError("pids", true)),
fmt.Sprintf("go3mf: XPath: /model/resources/texture2d[1]: %v", errors.NewParseAttrError("id", true)),
fmt.Sprintf("go3mf: XPath: /model/resources/colorgroup[2]/color[0]: %v", errors.NewParseAttrError("color", true)),
fmt.Sprintf("go3mf: XPath: /model/resources/texture2dgroup[3]: %v", errors.NewParseAttrError("texid", true)),
fmt.Sprintf("go3mf: XPath: /model/resources/texture2dgroup[3]/tex2coord[0]: %v", errors.NewParseAttrError("u", true)),
fmt.Sprintf("go3mf: XPath: /model/resources/texture2dgroup[3]/tex2coord[1]: %v", errors.NewParseAttrError("v", true)),
fmt.Sprintf("go3mf: XPath: /model/resources/compositematerials[4]: %v", errors.NewParseAttrError("matid", true)),
fmt.Sprintf("go3mf: XPath: /model/resources/compositematerials[4]/composite[1]: %v", errors.NewParseAttrError("values", true)),
fmt.Sprintf("go3mf: XPath: /model/resources/multiproperties[5]: %v", errors.NewParseAttrError("pids", true)),
}
got := new(go3mf.Model)
got.Path = "/3D/3dmodel.model"
Expand Down
56 changes: 28 additions & 28 deletions materials/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ func TestValidate(t *testing.T) {
&MultiProperties{ID: 2},
}}},
}}, []string{
fmt.Sprintf("/other.model/model/resources/colorgroup[0]: %v", errors.ErrEmptyResourceProps),
fmt.Sprintf("/that.model/model/resources/multiproperties[0]: %v", &errors.MissingFieldError{Name: attrPIDs}),
fmt.Sprintf("/that.model/model/resources/multiproperties[0]: %v", ErrMultiBlend),
fmt.Sprintf("/that.model/model/resources/multiproperties[0]: %v", errors.ErrEmptyResourceProps),
fmt.Sprintf("go3mf: Path: /other.model XPath: /model/resources/colorgroup[0]: %v", errors.ErrEmptyResourceProps),
fmt.Sprintf("go3mf: Path: /that.model XPath: /model/resources/multiproperties[0]: %v", &errors.MissingFieldError{Name: attrPIDs}),
fmt.Sprintf("go3mf: Path: /that.model XPath: /model/resources/multiproperties[0]: %v", ErrMultiBlend),
fmt.Sprintf("go3mf: Path: /that.model XPath: /model/resources/multiproperties[0]: %v", errors.ErrEmptyResourceProps),
}},
{"multi", &go3mf.Model{
Resources: go3mf.Resources{Assets: []go3mf.Asset{
Expand All @@ -48,25 +48,25 @@ func TestValidate(t *testing.T) {
&MultiProperties{ID: 9, Multis: []Multi{{PIndices: []uint32{}}}, PIDs: []uint32{1, 3}},
}},
}, []string{
fmt.Sprintf("model/resources/multiproperties[0]: %v", &errors.MissingFieldError{Name: attrPIDs}),
fmt.Sprintf("model/resources/multiproperties[0]: %v", ErrMultiBlend),
fmt.Sprintf("model/resources/multiproperties[0]: %v", errors.ErrEmptyResourceProps),
fmt.Sprintf("model/resources/multiproperties[1]: %v", ErrMultiRefMulti),
fmt.Sprintf("model/resources/multiproperties[1]: %v", errors.ErrMissingResource),
fmt.Sprintf("model/resources/multiproperties[6]/multi[0]: %v", errors.ErrIndexOutOfBounds),
fmt.Sprintf("model/resources/multiproperties[7]: %v", ErrMaterialMulti),
fmt.Sprintf("model/resources/multiproperties[7]: %v", ErrMultiColors),
fmt.Sprintf("model/resources/multiproperties[8]: %v", ErrMaterialMulti),
fmt.Sprintf("go3mf: XPath: /model/resources/multiproperties[0]: %v", &errors.MissingFieldError{Name: attrPIDs}),
fmt.Sprintf("go3mf: XPath: /model/resources/multiproperties[0]: %v", ErrMultiBlend),
fmt.Sprintf("go3mf: XPath: /model/resources/multiproperties[0]: %v", errors.ErrEmptyResourceProps),
fmt.Sprintf("go3mf: XPath: /model/resources/multiproperties[1]: %v", ErrMultiRefMulti),
fmt.Sprintf("go3mf: XPath: /model/resources/multiproperties[1]: %v", errors.ErrMissingResource),
fmt.Sprintf("go3mf: XPath: /model/resources/multiproperties[6]/multi[0]: %v", errors.ErrIndexOutOfBounds),
fmt.Sprintf("go3mf: XPath: /model/resources/multiproperties[7]: %v", ErrMaterialMulti),
fmt.Sprintf("go3mf: XPath: /model/resources/multiproperties[7]: %v", ErrMultiColors),
fmt.Sprintf("go3mf: XPath: /model/resources/multiproperties[8]: %v", ErrMaterialMulti),
}},
{"missingTextPart", &go3mf.Model{
Resources: go3mf.Resources{Assets: []go3mf.Asset{
&Texture2D{ID: 1},
&Texture2D{ID: 2, ContentType: TextureTypePNG, Path: "/a.png"},
}},
}, []string{
fmt.Sprintf("model/resources/texture2d[0]: %v", &errors.MissingFieldError{Name: attrPath}),
fmt.Sprintf("model/resources/texture2d[0]: %v", &errors.MissingFieldError{Name: attrContentType}),
fmt.Sprintf("model/resources/texture2d[1]: %v", ErrMissingTexturePart),
fmt.Sprintf("go3mf: XPath: /model/resources/texture2d[0]: %v", &errors.MissingFieldError{Name: attrPath}),
fmt.Sprintf("go3mf: XPath: /model/resources/texture2d[0]: %v", &errors.MissingFieldError{Name: attrContentType}),
fmt.Sprintf("go3mf: XPath: /model/resources/texture2d[1]: %v", ErrMissingTexturePart),
}},
{"textureGroup", &go3mf.Model{
Attachments: []go3mf.Attachment{{Path: "/a.png"}},
Expand All @@ -78,10 +78,10 @@ func TestValidate(t *testing.T) {
&Texture2DGroup{ID: 5, TextureID: 100, Coords: []TextureCoord{{}}},
}},
}, []string{
fmt.Sprintf("model/resources/texture2dgroup[1]: %v", &errors.MissingFieldError{Name: attrTexID}),
fmt.Sprintf("model/resources/texture2dgroup[1]: %v", errors.ErrEmptyResourceProps),
fmt.Sprintf("model/resources/texture2dgroup[3]: %v", ErrTextureReference),
fmt.Sprintf("model/resources/texture2dgroup[4]: %v", ErrTextureReference),
fmt.Sprintf("go3mf: XPath: /model/resources/texture2dgroup[1]: %v", &errors.MissingFieldError{Name: attrTexID}),
fmt.Sprintf("go3mf: XPath: /model/resources/texture2dgroup[1]: %v", errors.ErrEmptyResourceProps),
fmt.Sprintf("go3mf: XPath: /model/resources/texture2dgroup[3]: %v", ErrTextureReference),
fmt.Sprintf("go3mf: XPath: /model/resources/texture2dgroup[4]: %v", ErrTextureReference),
}},
{"colorGroup", &go3mf.Model{
Resources: go3mf.Resources{Assets: []go3mf.Asset{
Expand All @@ -90,8 +90,8 @@ func TestValidate(t *testing.T) {
&ColorGroup{ID: 3, Colors: []color.RGBA{{R: 1}, {}}},
}},
}, []string{
fmt.Sprintf("model/resources/colorgroup[0]: %v", errors.ErrEmptyResourceProps),
fmt.Sprintf("model/resources/colorgroup[2]/color[1]: %v", &errors.MissingFieldError{Name: attrColor}),
fmt.Sprintf("go3mf: XPath: /model/resources/colorgroup[0]: %v", errors.ErrEmptyResourceProps),
fmt.Sprintf("go3mf: XPath: /model/resources/colorgroup[2]/color[1]: %v", &errors.MissingFieldError{Name: attrColor}),
}},
{"composite", &go3mf.Model{
Resources: go3mf.Resources{Assets: []go3mf.Asset{
Expand All @@ -105,12 +105,12 @@ func TestValidate(t *testing.T) {
&CompositeMaterials{ID: 5, MaterialID: 2, Indices: []uint32{0, 1}, Composites: []Composite{{Values: []float32{1, 2}}}},
&CompositeMaterials{ID: 6, MaterialID: 100, Indices: []uint32{0, 1}, Composites: []Composite{{Values: []float32{1, 2}}}},
}}}, []string{
fmt.Sprintf("model/resources/compositematerials[1]: %v", &errors.MissingFieldError{Name: attrMatID}),
fmt.Sprintf("model/resources/compositematerials[1]: %v", &errors.MissingFieldError{Name: attrMatIndices}),
fmt.Sprintf("model/resources/compositematerials[1]: %v", errors.ErrEmptyResourceProps),
fmt.Sprintf("model/resources/compositematerials[3]: %v", errors.ErrIndexOutOfBounds),
fmt.Sprintf("model/resources/compositematerials[4]: %v", ErrCompositeBase),
fmt.Sprintf("model/resources/compositematerials[5]: %v", errors.ErrMissingResource),
fmt.Sprintf("go3mf: XPath: /model/resources/compositematerials[1]: %v", &errors.MissingFieldError{Name: attrMatID}),
fmt.Sprintf("go3mf: XPath: /model/resources/compositematerials[1]: %v", &errors.MissingFieldError{Name: attrMatIndices}),
fmt.Sprintf("go3mf: XPath: /model/resources/compositematerials[1]: %v", errors.ErrEmptyResourceProps),
fmt.Sprintf("go3mf: XPath: /model/resources/compositematerials[3]: %v", errors.ErrIndexOutOfBounds),
fmt.Sprintf("go3mf: XPath: /model/resources/compositematerials[4]: %v", ErrCompositeBase),
fmt.Sprintf("go3mf: XPath: /model/resources/compositematerials[5]: %v", errors.ErrMissingResource),
}},
}
for _, tt := range tests {
Expand Down
8 changes: 4 additions & 4 deletions production/decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ func TestDecode(t *testing.T) {

func TestDecode_warns(t *testing.T) {
want := []string{
fmt.Sprintf("model/resources/object[1]: %v", &errors.ParseAttrError{Required: true, Name: "UUID"}),
fmt.Sprintf("model/resources/object[1]/components/component[0]: %v", &errors.ParseAttrError{Required: true, Name: "UUID"}),
fmt.Sprintf("model/build: %v", &errors.ParseAttrError{Required: true, Name: "UUID"}),
fmt.Sprintf("model/build/item[0]: %v", &errors.ParseAttrError{Required: true, Name: "UUID"}),
fmt.Sprintf("go3mf: XPath: /model/resources/object[1]: %v", &errors.ParseAttrError{Required: true, Name: "UUID"}),
fmt.Sprintf("go3mf: XPath: /model/resources/object[1]/components/component[0]: %v", &errors.ParseAttrError{Required: true, Name: "UUID"}),
fmt.Sprintf("go3mf: XPath: /model/build: %v", &errors.ParseAttrError{Required: true, Name: "UUID"}),
fmt.Sprintf("go3mf: XPath: /model/build/item[0]: %v", &errors.ParseAttrError{Required: true, Name: "UUID"}),
}
got := new(go3mf.Model)
got.Path = "/3D/3dmodel.model"
Expand Down
Loading

0 comments on commit 207a8cb

Please sign in to comment.