Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
abf5de69
Commit
abf5de69
authored
Feb 12, 2026
by
yangjianbo
Browse files
Merge branch 'main' into test
parents
7582dc53
174d7c77
Changes
63
Hide whitespace changes
Inline
Side-by-side
backend/ent/errorpassthroughrule.go
View file @
abf5de69
...
@@ -44,6 +44,8 @@ type ErrorPassthroughRule struct {
...
@@ -44,6 +44,8 @@ type ErrorPassthroughRule struct {
PassthroughBody
bool
`json:"passthrough_body,omitempty"`
PassthroughBody
bool
`json:"passthrough_body,omitempty"`
// CustomMessage holds the value of the "custom_message" field.
// CustomMessage holds the value of the "custom_message" field.
CustomMessage
*
string
`json:"custom_message,omitempty"`
CustomMessage
*
string
`json:"custom_message,omitempty"`
// SkipMonitoring holds the value of the "skip_monitoring" field.
SkipMonitoring
bool
`json:"skip_monitoring,omitempty"`
// Description holds the value of the "description" field.
// Description holds the value of the "description" field.
Description
*
string
`json:"description,omitempty"`
Description
*
string
`json:"description,omitempty"`
selectValues
sql
.
SelectValues
selectValues
sql
.
SelectValues
...
@@ -56,7 +58,7 @@ func (*ErrorPassthroughRule) scanValues(columns []string) ([]any, error) {
...
@@ -56,7 +58,7 @@ func (*ErrorPassthroughRule) scanValues(columns []string) ([]any, error) {
switch
columns
[
i
]
{
switch
columns
[
i
]
{
case
errorpassthroughrule
.
FieldErrorCodes
,
errorpassthroughrule
.
FieldKeywords
,
errorpassthroughrule
.
FieldPlatforms
:
case
errorpassthroughrule
.
FieldErrorCodes
,
errorpassthroughrule
.
FieldKeywords
,
errorpassthroughrule
.
FieldPlatforms
:
values
[
i
]
=
new
([]
byte
)
values
[
i
]
=
new
([]
byte
)
case
errorpassthroughrule
.
FieldEnabled
,
errorpassthroughrule
.
FieldPassthroughCode
,
errorpassthroughrule
.
FieldPassthroughBody
:
case
errorpassthroughrule
.
FieldEnabled
,
errorpassthroughrule
.
FieldPassthroughCode
,
errorpassthroughrule
.
FieldPassthroughBody
,
errorpassthroughrule
.
FieldSkipMonitoring
:
values
[
i
]
=
new
(
sql
.
NullBool
)
values
[
i
]
=
new
(
sql
.
NullBool
)
case
errorpassthroughrule
.
FieldID
,
errorpassthroughrule
.
FieldPriority
,
errorpassthroughrule
.
FieldResponseCode
:
case
errorpassthroughrule
.
FieldID
,
errorpassthroughrule
.
FieldPriority
,
errorpassthroughrule
.
FieldResponseCode
:
values
[
i
]
=
new
(
sql
.
NullInt64
)
values
[
i
]
=
new
(
sql
.
NullInt64
)
...
@@ -171,6 +173,12 @@ func (_m *ErrorPassthroughRule) assignValues(columns []string, values []any) err
...
@@ -171,6 +173,12 @@ func (_m *ErrorPassthroughRule) assignValues(columns []string, values []any) err
_m
.
CustomMessage
=
new
(
string
)
_m
.
CustomMessage
=
new
(
string
)
*
_m
.
CustomMessage
=
value
.
String
*
_m
.
CustomMessage
=
value
.
String
}
}
case
errorpassthroughrule
.
FieldSkipMonitoring
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullBool
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field skip_monitoring"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
SkipMonitoring
=
value
.
Bool
}
case
errorpassthroughrule
.
FieldDescription
:
case
errorpassthroughrule
.
FieldDescription
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullString
);
!
ok
{
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullString
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field description"
,
values
[
i
])
return
fmt
.
Errorf
(
"unexpected type %T for field description"
,
values
[
i
])
...
@@ -257,6 +265,9 @@ func (_m *ErrorPassthroughRule) String() string {
...
@@ -257,6 +265,9 @@ func (_m *ErrorPassthroughRule) String() string {
builder
.
WriteString
(
*
v
)
builder
.
WriteString
(
*
v
)
}
}
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"skip_monitoring="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
SkipMonitoring
))
builder
.
WriteString
(
", "
)
if
v
:=
_m
.
Description
;
v
!=
nil
{
if
v
:=
_m
.
Description
;
v
!=
nil
{
builder
.
WriteString
(
"description="
)
builder
.
WriteString
(
"description="
)
builder
.
WriteString
(
*
v
)
builder
.
WriteString
(
*
v
)
...
...
backend/ent/errorpassthroughrule/errorpassthroughrule.go
View file @
abf5de69
...
@@ -39,6 +39,8 @@ const (
...
@@ -39,6 +39,8 @@ const (
FieldPassthroughBody
=
"passthrough_body"
FieldPassthroughBody
=
"passthrough_body"
// FieldCustomMessage holds the string denoting the custom_message field in the database.
// FieldCustomMessage holds the string denoting the custom_message field in the database.
FieldCustomMessage
=
"custom_message"
FieldCustomMessage
=
"custom_message"
// FieldSkipMonitoring holds the string denoting the skip_monitoring field in the database.
FieldSkipMonitoring
=
"skip_monitoring"
// FieldDescription holds the string denoting the description field in the database.
// FieldDescription holds the string denoting the description field in the database.
FieldDescription
=
"description"
FieldDescription
=
"description"
// Table holds the table name of the errorpassthroughrule in the database.
// Table holds the table name of the errorpassthroughrule in the database.
...
@@ -61,6 +63,7 @@ var Columns = []string{
...
@@ -61,6 +63,7 @@ var Columns = []string{
FieldResponseCode
,
FieldResponseCode
,
FieldPassthroughBody
,
FieldPassthroughBody
,
FieldCustomMessage
,
FieldCustomMessage
,
FieldSkipMonitoring
,
FieldDescription
,
FieldDescription
,
}
}
...
@@ -95,6 +98,8 @@ var (
...
@@ -95,6 +98,8 @@ var (
DefaultPassthroughCode
bool
DefaultPassthroughCode
bool
// DefaultPassthroughBody holds the default value on creation for the "passthrough_body" field.
// DefaultPassthroughBody holds the default value on creation for the "passthrough_body" field.
DefaultPassthroughBody
bool
DefaultPassthroughBody
bool
// DefaultSkipMonitoring holds the default value on creation for the "skip_monitoring" field.
DefaultSkipMonitoring
bool
)
)
// OrderOption defines the ordering options for the ErrorPassthroughRule queries.
// OrderOption defines the ordering options for the ErrorPassthroughRule queries.
...
@@ -155,6 +160,11 @@ func ByCustomMessage(opts ...sql.OrderTermOption) OrderOption {
...
@@ -155,6 +160,11 @@ func ByCustomMessage(opts ...sql.OrderTermOption) OrderOption {
return
sql
.
OrderByField
(
FieldCustomMessage
,
opts
...
)
.
ToFunc
()
return
sql
.
OrderByField
(
FieldCustomMessage
,
opts
...
)
.
ToFunc
()
}
}
// BySkipMonitoring orders the results by the skip_monitoring field.
func
BySkipMonitoring
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldSkipMonitoring
,
opts
...
)
.
ToFunc
()
}
// ByDescription orders the results by the description field.
// ByDescription orders the results by the description field.
func
ByDescription
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
func
ByDescription
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldDescription
,
opts
...
)
.
ToFunc
()
return
sql
.
OrderByField
(
FieldDescription
,
opts
...
)
.
ToFunc
()
...
...
backend/ent/errorpassthroughrule/where.go
View file @
abf5de69
...
@@ -104,6 +104,11 @@ func CustomMessage(v string) predicate.ErrorPassthroughRule {
...
@@ -104,6 +104,11 @@ func CustomMessage(v string) predicate.ErrorPassthroughRule {
return
predicate
.
ErrorPassthroughRule
(
sql
.
FieldEQ
(
FieldCustomMessage
,
v
))
return
predicate
.
ErrorPassthroughRule
(
sql
.
FieldEQ
(
FieldCustomMessage
,
v
))
}
}
// SkipMonitoring applies equality check predicate on the "skip_monitoring" field. It's identical to SkipMonitoringEQ.
func
SkipMonitoring
(
v
bool
)
predicate
.
ErrorPassthroughRule
{
return
predicate
.
ErrorPassthroughRule
(
sql
.
FieldEQ
(
FieldSkipMonitoring
,
v
))
}
// Description applies equality check predicate on the "description" field. It's identical to DescriptionEQ.
// Description applies equality check predicate on the "description" field. It's identical to DescriptionEQ.
func
Description
(
v
string
)
predicate
.
ErrorPassthroughRule
{
func
Description
(
v
string
)
predicate
.
ErrorPassthroughRule
{
return
predicate
.
ErrorPassthroughRule
(
sql
.
FieldEQ
(
FieldDescription
,
v
))
return
predicate
.
ErrorPassthroughRule
(
sql
.
FieldEQ
(
FieldDescription
,
v
))
...
@@ -544,6 +549,16 @@ func CustomMessageContainsFold(v string) predicate.ErrorPassthroughRule {
...
@@ -544,6 +549,16 @@ func CustomMessageContainsFold(v string) predicate.ErrorPassthroughRule {
return
predicate
.
ErrorPassthroughRule
(
sql
.
FieldContainsFold
(
FieldCustomMessage
,
v
))
return
predicate
.
ErrorPassthroughRule
(
sql
.
FieldContainsFold
(
FieldCustomMessage
,
v
))
}
}
// SkipMonitoringEQ applies the EQ predicate on the "skip_monitoring" field.
func
SkipMonitoringEQ
(
v
bool
)
predicate
.
ErrorPassthroughRule
{
return
predicate
.
ErrorPassthroughRule
(
sql
.
FieldEQ
(
FieldSkipMonitoring
,
v
))
}
// SkipMonitoringNEQ applies the NEQ predicate on the "skip_monitoring" field.
func
SkipMonitoringNEQ
(
v
bool
)
predicate
.
ErrorPassthroughRule
{
return
predicate
.
ErrorPassthroughRule
(
sql
.
FieldNEQ
(
FieldSkipMonitoring
,
v
))
}
// DescriptionEQ applies the EQ predicate on the "description" field.
// DescriptionEQ applies the EQ predicate on the "description" field.
func
DescriptionEQ
(
v
string
)
predicate
.
ErrorPassthroughRule
{
func
DescriptionEQ
(
v
string
)
predicate
.
ErrorPassthroughRule
{
return
predicate
.
ErrorPassthroughRule
(
sql
.
FieldEQ
(
FieldDescription
,
v
))
return
predicate
.
ErrorPassthroughRule
(
sql
.
FieldEQ
(
FieldDescription
,
v
))
...
...
backend/ent/errorpassthroughrule_create.go
View file @
abf5de69
...
@@ -172,6 +172,20 @@ func (_c *ErrorPassthroughRuleCreate) SetNillableCustomMessage(v *string) *Error
...
@@ -172,6 +172,20 @@ func (_c *ErrorPassthroughRuleCreate) SetNillableCustomMessage(v *string) *Error
return
_c
return
_c
}
}
// SetSkipMonitoring sets the "skip_monitoring" field.
func
(
_c
*
ErrorPassthroughRuleCreate
)
SetSkipMonitoring
(
v
bool
)
*
ErrorPassthroughRuleCreate
{
_c
.
mutation
.
SetSkipMonitoring
(
v
)
return
_c
}
// SetNillableSkipMonitoring sets the "skip_monitoring" field if the given value is not nil.
func
(
_c
*
ErrorPassthroughRuleCreate
)
SetNillableSkipMonitoring
(
v
*
bool
)
*
ErrorPassthroughRuleCreate
{
if
v
!=
nil
{
_c
.
SetSkipMonitoring
(
*
v
)
}
return
_c
}
// SetDescription sets the "description" field.
// SetDescription sets the "description" field.
func
(
_c
*
ErrorPassthroughRuleCreate
)
SetDescription
(
v
string
)
*
ErrorPassthroughRuleCreate
{
func
(
_c
*
ErrorPassthroughRuleCreate
)
SetDescription
(
v
string
)
*
ErrorPassthroughRuleCreate
{
_c
.
mutation
.
SetDescription
(
v
)
_c
.
mutation
.
SetDescription
(
v
)
...
@@ -249,6 +263,10 @@ func (_c *ErrorPassthroughRuleCreate) defaults() {
...
@@ -249,6 +263,10 @@ func (_c *ErrorPassthroughRuleCreate) defaults() {
v
:=
errorpassthroughrule
.
DefaultPassthroughBody
v
:=
errorpassthroughrule
.
DefaultPassthroughBody
_c
.
mutation
.
SetPassthroughBody
(
v
)
_c
.
mutation
.
SetPassthroughBody
(
v
)
}
}
if
_
,
ok
:=
_c
.
mutation
.
SkipMonitoring
();
!
ok
{
v
:=
errorpassthroughrule
.
DefaultSkipMonitoring
_c
.
mutation
.
SetSkipMonitoring
(
v
)
}
}
}
// check runs all checks and user-defined validators on the builder.
// check runs all checks and user-defined validators on the builder.
...
@@ -287,6 +305,9 @@ func (_c *ErrorPassthroughRuleCreate) check() error {
...
@@ -287,6 +305,9 @@ func (_c *ErrorPassthroughRuleCreate) check() error {
if
_
,
ok
:=
_c
.
mutation
.
PassthroughBody
();
!
ok
{
if
_
,
ok
:=
_c
.
mutation
.
PassthroughBody
();
!
ok
{
return
&
ValidationError
{
Name
:
"passthrough_body"
,
err
:
errors
.
New
(
`ent: missing required field "ErrorPassthroughRule.passthrough_body"`
)}
return
&
ValidationError
{
Name
:
"passthrough_body"
,
err
:
errors
.
New
(
`ent: missing required field "ErrorPassthroughRule.passthrough_body"`
)}
}
}
if
_
,
ok
:=
_c
.
mutation
.
SkipMonitoring
();
!
ok
{
return
&
ValidationError
{
Name
:
"skip_monitoring"
,
err
:
errors
.
New
(
`ent: missing required field "ErrorPassthroughRule.skip_monitoring"`
)}
}
return
nil
return
nil
}
}
...
@@ -366,6 +387,10 @@ func (_c *ErrorPassthroughRuleCreate) createSpec() (*ErrorPassthroughRule, *sqlg
...
@@ -366,6 +387,10 @@ func (_c *ErrorPassthroughRuleCreate) createSpec() (*ErrorPassthroughRule, *sqlg
_spec
.
SetField
(
errorpassthroughrule
.
FieldCustomMessage
,
field
.
TypeString
,
value
)
_spec
.
SetField
(
errorpassthroughrule
.
FieldCustomMessage
,
field
.
TypeString
,
value
)
_node
.
CustomMessage
=
&
value
_node
.
CustomMessage
=
&
value
}
}
if
value
,
ok
:=
_c
.
mutation
.
SkipMonitoring
();
ok
{
_spec
.
SetField
(
errorpassthroughrule
.
FieldSkipMonitoring
,
field
.
TypeBool
,
value
)
_node
.
SkipMonitoring
=
value
}
if
value
,
ok
:=
_c
.
mutation
.
Description
();
ok
{
if
value
,
ok
:=
_c
.
mutation
.
Description
();
ok
{
_spec
.
SetField
(
errorpassthroughrule
.
FieldDescription
,
field
.
TypeString
,
value
)
_spec
.
SetField
(
errorpassthroughrule
.
FieldDescription
,
field
.
TypeString
,
value
)
_node
.
Description
=
&
value
_node
.
Description
=
&
value
...
@@ -608,6 +633,18 @@ func (u *ErrorPassthroughRuleUpsert) ClearCustomMessage() *ErrorPassthroughRuleU
...
@@ -608,6 +633,18 @@ func (u *ErrorPassthroughRuleUpsert) ClearCustomMessage() *ErrorPassthroughRuleU
return
u
return
u
}
}
// SetSkipMonitoring sets the "skip_monitoring" field.
func
(
u
*
ErrorPassthroughRuleUpsert
)
SetSkipMonitoring
(
v
bool
)
*
ErrorPassthroughRuleUpsert
{
u
.
Set
(
errorpassthroughrule
.
FieldSkipMonitoring
,
v
)
return
u
}
// UpdateSkipMonitoring sets the "skip_monitoring" field to the value that was provided on create.
func
(
u
*
ErrorPassthroughRuleUpsert
)
UpdateSkipMonitoring
()
*
ErrorPassthroughRuleUpsert
{
u
.
SetExcluded
(
errorpassthroughrule
.
FieldSkipMonitoring
)
return
u
}
// SetDescription sets the "description" field.
// SetDescription sets the "description" field.
func
(
u
*
ErrorPassthroughRuleUpsert
)
SetDescription
(
v
string
)
*
ErrorPassthroughRuleUpsert
{
func
(
u
*
ErrorPassthroughRuleUpsert
)
SetDescription
(
v
string
)
*
ErrorPassthroughRuleUpsert
{
u
.
Set
(
errorpassthroughrule
.
FieldDescription
,
v
)
u
.
Set
(
errorpassthroughrule
.
FieldDescription
,
v
)
...
@@ -888,6 +925,20 @@ func (u *ErrorPassthroughRuleUpsertOne) ClearCustomMessage() *ErrorPassthroughRu
...
@@ -888,6 +925,20 @@ func (u *ErrorPassthroughRuleUpsertOne) ClearCustomMessage() *ErrorPassthroughRu
})
})
}
}
// SetSkipMonitoring sets the "skip_monitoring" field.
func
(
u
*
ErrorPassthroughRuleUpsertOne
)
SetSkipMonitoring
(
v
bool
)
*
ErrorPassthroughRuleUpsertOne
{
return
u
.
Update
(
func
(
s
*
ErrorPassthroughRuleUpsert
)
{
s
.
SetSkipMonitoring
(
v
)
})
}
// UpdateSkipMonitoring sets the "skip_monitoring" field to the value that was provided on create.
func
(
u
*
ErrorPassthroughRuleUpsertOne
)
UpdateSkipMonitoring
()
*
ErrorPassthroughRuleUpsertOne
{
return
u
.
Update
(
func
(
s
*
ErrorPassthroughRuleUpsert
)
{
s
.
UpdateSkipMonitoring
()
})
}
// SetDescription sets the "description" field.
// SetDescription sets the "description" field.
func
(
u
*
ErrorPassthroughRuleUpsertOne
)
SetDescription
(
v
string
)
*
ErrorPassthroughRuleUpsertOne
{
func
(
u
*
ErrorPassthroughRuleUpsertOne
)
SetDescription
(
v
string
)
*
ErrorPassthroughRuleUpsertOne
{
return
u
.
Update
(
func
(
s
*
ErrorPassthroughRuleUpsert
)
{
return
u
.
Update
(
func
(
s
*
ErrorPassthroughRuleUpsert
)
{
...
@@ -1337,6 +1388,20 @@ func (u *ErrorPassthroughRuleUpsertBulk) ClearCustomMessage() *ErrorPassthroughR
...
@@ -1337,6 +1388,20 @@ func (u *ErrorPassthroughRuleUpsertBulk) ClearCustomMessage() *ErrorPassthroughR
})
})
}
}
// SetSkipMonitoring sets the "skip_monitoring" field.
func
(
u
*
ErrorPassthroughRuleUpsertBulk
)
SetSkipMonitoring
(
v
bool
)
*
ErrorPassthroughRuleUpsertBulk
{
return
u
.
Update
(
func
(
s
*
ErrorPassthroughRuleUpsert
)
{
s
.
SetSkipMonitoring
(
v
)
})
}
// UpdateSkipMonitoring sets the "skip_monitoring" field to the value that was provided on create.
func
(
u
*
ErrorPassthroughRuleUpsertBulk
)
UpdateSkipMonitoring
()
*
ErrorPassthroughRuleUpsertBulk
{
return
u
.
Update
(
func
(
s
*
ErrorPassthroughRuleUpsert
)
{
s
.
UpdateSkipMonitoring
()
})
}
// SetDescription sets the "description" field.
// SetDescription sets the "description" field.
func
(
u
*
ErrorPassthroughRuleUpsertBulk
)
SetDescription
(
v
string
)
*
ErrorPassthroughRuleUpsertBulk
{
func
(
u
*
ErrorPassthroughRuleUpsertBulk
)
SetDescription
(
v
string
)
*
ErrorPassthroughRuleUpsertBulk
{
return
u
.
Update
(
func
(
s
*
ErrorPassthroughRuleUpsert
)
{
return
u
.
Update
(
func
(
s
*
ErrorPassthroughRuleUpsert
)
{
...
...
backend/ent/errorpassthroughrule_update.go
View file @
abf5de69
...
@@ -227,6 +227,20 @@ func (_u *ErrorPassthroughRuleUpdate) ClearCustomMessage() *ErrorPassthroughRule
...
@@ -227,6 +227,20 @@ func (_u *ErrorPassthroughRuleUpdate) ClearCustomMessage() *ErrorPassthroughRule
return
_u
return
_u
}
}
// SetSkipMonitoring sets the "skip_monitoring" field.
func
(
_u
*
ErrorPassthroughRuleUpdate
)
SetSkipMonitoring
(
v
bool
)
*
ErrorPassthroughRuleUpdate
{
_u
.
mutation
.
SetSkipMonitoring
(
v
)
return
_u
}
// SetNillableSkipMonitoring sets the "skip_monitoring" field if the given value is not nil.
func
(
_u
*
ErrorPassthroughRuleUpdate
)
SetNillableSkipMonitoring
(
v
*
bool
)
*
ErrorPassthroughRuleUpdate
{
if
v
!=
nil
{
_u
.
SetSkipMonitoring
(
*
v
)
}
return
_u
}
// SetDescription sets the "description" field.
// SetDescription sets the "description" field.
func
(
_u
*
ErrorPassthroughRuleUpdate
)
SetDescription
(
v
string
)
*
ErrorPassthroughRuleUpdate
{
func
(
_u
*
ErrorPassthroughRuleUpdate
)
SetDescription
(
v
string
)
*
ErrorPassthroughRuleUpdate
{
_u
.
mutation
.
SetDescription
(
v
)
_u
.
mutation
.
SetDescription
(
v
)
...
@@ -387,6 +401,9 @@ func (_u *ErrorPassthroughRuleUpdate) sqlSave(ctx context.Context) (_node int, e
...
@@ -387,6 +401,9 @@ func (_u *ErrorPassthroughRuleUpdate) sqlSave(ctx context.Context) (_node int, e
if
_u
.
mutation
.
CustomMessageCleared
()
{
if
_u
.
mutation
.
CustomMessageCleared
()
{
_spec
.
ClearField
(
errorpassthroughrule
.
FieldCustomMessage
,
field
.
TypeString
)
_spec
.
ClearField
(
errorpassthroughrule
.
FieldCustomMessage
,
field
.
TypeString
)
}
}
if
value
,
ok
:=
_u
.
mutation
.
SkipMonitoring
();
ok
{
_spec
.
SetField
(
errorpassthroughrule
.
FieldSkipMonitoring
,
field
.
TypeBool
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Description
();
ok
{
if
value
,
ok
:=
_u
.
mutation
.
Description
();
ok
{
_spec
.
SetField
(
errorpassthroughrule
.
FieldDescription
,
field
.
TypeString
,
value
)
_spec
.
SetField
(
errorpassthroughrule
.
FieldDescription
,
field
.
TypeString
,
value
)
}
}
...
@@ -611,6 +628,20 @@ func (_u *ErrorPassthroughRuleUpdateOne) ClearCustomMessage() *ErrorPassthroughR
...
@@ -611,6 +628,20 @@ func (_u *ErrorPassthroughRuleUpdateOne) ClearCustomMessage() *ErrorPassthroughR
return
_u
return
_u
}
}
// SetSkipMonitoring sets the "skip_monitoring" field.
func
(
_u
*
ErrorPassthroughRuleUpdateOne
)
SetSkipMonitoring
(
v
bool
)
*
ErrorPassthroughRuleUpdateOne
{
_u
.
mutation
.
SetSkipMonitoring
(
v
)
return
_u
}
// SetNillableSkipMonitoring sets the "skip_monitoring" field if the given value is not nil.
func
(
_u
*
ErrorPassthroughRuleUpdateOne
)
SetNillableSkipMonitoring
(
v
*
bool
)
*
ErrorPassthroughRuleUpdateOne
{
if
v
!=
nil
{
_u
.
SetSkipMonitoring
(
*
v
)
}
return
_u
}
// SetDescription sets the "description" field.
// SetDescription sets the "description" field.
func
(
_u
*
ErrorPassthroughRuleUpdateOne
)
SetDescription
(
v
string
)
*
ErrorPassthroughRuleUpdateOne
{
func
(
_u
*
ErrorPassthroughRuleUpdateOne
)
SetDescription
(
v
string
)
*
ErrorPassthroughRuleUpdateOne
{
_u
.
mutation
.
SetDescription
(
v
)
_u
.
mutation
.
SetDescription
(
v
)
...
@@ -801,6 +832,9 @@ func (_u *ErrorPassthroughRuleUpdateOne) sqlSave(ctx context.Context) (_node *Er
...
@@ -801,6 +832,9 @@ func (_u *ErrorPassthroughRuleUpdateOne) sqlSave(ctx context.Context) (_node *Er
if
_u
.
mutation
.
CustomMessageCleared
()
{
if
_u
.
mutation
.
CustomMessageCleared
()
{
_spec
.
ClearField
(
errorpassthroughrule
.
FieldCustomMessage
,
field
.
TypeString
)
_spec
.
ClearField
(
errorpassthroughrule
.
FieldCustomMessage
,
field
.
TypeString
)
}
}
if
value
,
ok
:=
_u
.
mutation
.
SkipMonitoring
();
ok
{
_spec
.
SetField
(
errorpassthroughrule
.
FieldSkipMonitoring
,
field
.
TypeBool
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Description
();
ok
{
if
value
,
ok
:=
_u
.
mutation
.
Description
();
ok
{
_spec
.
SetField
(
errorpassthroughrule
.
FieldDescription
,
field
.
TypeString
,
value
)
_spec
.
SetField
(
errorpassthroughrule
.
FieldDescription
,
field
.
TypeString
,
value
)
}
}
...
...
backend/ent/migrate/schema.go
View file @
abf5de69
...
@@ -325,6 +325,7 @@ var (
...
@@ -325,6 +325,7 @@ var (
{
Name
:
"response_code"
,
Type
:
field
.
TypeInt
,
Nullable
:
true
},
{
Name
:
"response_code"
,
Type
:
field
.
TypeInt
,
Nullable
:
true
},
{
Name
:
"passthrough_body"
,
Type
:
field
.
TypeBool
,
Default
:
true
},
{
Name
:
"passthrough_body"
,
Type
:
field
.
TypeBool
,
Default
:
true
},
{
Name
:
"custom_message"
,
Type
:
field
.
TypeString
,
Nullable
:
true
,
Size
:
2147483647
},
{
Name
:
"custom_message"
,
Type
:
field
.
TypeString
,
Nullable
:
true
,
Size
:
2147483647
},
{
Name
:
"skip_monitoring"
,
Type
:
field
.
TypeBool
,
Default
:
false
},
{
Name
:
"description"
,
Type
:
field
.
TypeString
,
Nullable
:
true
,
Size
:
2147483647
},
{
Name
:
"description"
,
Type
:
field
.
TypeString
,
Nullable
:
true
,
Size
:
2147483647
},
}
}
// ErrorPassthroughRulesTable holds the schema information for the "error_passthrough_rules" table.
// ErrorPassthroughRulesTable holds the schema information for the "error_passthrough_rules" table.
...
...
backend/ent/mutation.go
View file @
abf5de69
...
@@ -5778,6 +5778,7 @@ type ErrorPassthroughRuleMutation struct {
...
@@ -5778,6 +5778,7 @@ type ErrorPassthroughRuleMutation struct {
addresponse_code *int
addresponse_code *int
passthrough_body *bool
passthrough_body *bool
custom_message *string
custom_message *string
skip_monitoring *bool
description *string
description *string
clearedFields map[string]struct{}
clearedFields map[string]struct{}
done bool
done bool
...
@@ -6505,6 +6506,42 @@ func (m *ErrorPassthroughRuleMutation) ResetCustomMessage() {
...
@@ -6505,6 +6506,42 @@ func (m *ErrorPassthroughRuleMutation) ResetCustomMessage() {
delete(m.clearedFields, errorpassthroughrule.FieldCustomMessage)
delete(m.clearedFields, errorpassthroughrule.FieldCustomMessage)
}
}
// SetSkipMonitoring sets the "skip_monitoring" field.
func (m *ErrorPassthroughRuleMutation) SetSkipMonitoring(b bool) {
m.skip_monitoring = &b
}
// SkipMonitoring returns the value of the "skip_monitoring" field in the mutation.
func (m *ErrorPassthroughRuleMutation) SkipMonitoring() (r bool, exists bool) {
v := m.skip_monitoring
if v == nil {
return
}
return *v, true
}
// OldSkipMonitoring returns the old "skip_monitoring" field's value of the ErrorPassthroughRule entity.
// If the ErrorPassthroughRule object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *ErrorPassthroughRuleMutation) OldSkipMonitoring(ctx context.Context) (v bool, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldSkipMonitoring is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldSkipMonitoring requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldSkipMonitoring: %w", err)
}
return oldValue.SkipMonitoring, nil
}
// ResetSkipMonitoring resets all changes to the "skip_monitoring" field.
func (m *ErrorPassthroughRuleMutation) ResetSkipMonitoring() {
m.skip_monitoring = nil
}
// SetDescription sets the "description" field.
// SetDescription sets the "description" field.
func (m *ErrorPassthroughRuleMutation) SetDescription(s string) {
func (m *ErrorPassthroughRuleMutation) SetDescription(s string) {
m.description = &s
m.description = &s
...
@@ -6588,7 +6625,7 @@ func (m *ErrorPassthroughRuleMutation) Type() string {
...
@@ -6588,7 +6625,7 @@ func (m *ErrorPassthroughRuleMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call
// order to get all numeric fields that were incremented/decremented, call
// AddedFields().
// AddedFields().
func (m *ErrorPassthroughRuleMutation) Fields() []string {
func (m *ErrorPassthroughRuleMutation) Fields() []string {
fields := make([]string, 0, 1
4
)
fields := make([]string, 0, 1
5
)
if m.created_at != nil {
if m.created_at != nil {
fields = append(fields, errorpassthroughrule.FieldCreatedAt)
fields = append(fields, errorpassthroughrule.FieldCreatedAt)
}
}
...
@@ -6628,6 +6665,9 @@ func (m *ErrorPassthroughRuleMutation) Fields() []string {
...
@@ -6628,6 +6665,9 @@ func (m *ErrorPassthroughRuleMutation) Fields() []string {
if m.custom_message != nil {
if m.custom_message != nil {
fields = append(fields, errorpassthroughrule.FieldCustomMessage)
fields = append(fields, errorpassthroughrule.FieldCustomMessage)
}
}
if m.skip_monitoring != nil {
fields = append(fields, errorpassthroughrule.FieldSkipMonitoring)
}
if m.description != nil {
if m.description != nil {
fields = append(fields, errorpassthroughrule.FieldDescription)
fields = append(fields, errorpassthroughrule.FieldDescription)
}
}
...
@@ -6665,6 +6705,8 @@ func (m *ErrorPassthroughRuleMutation) Field(name string) (ent.Value, bool) {
...
@@ -6665,6 +6705,8 @@ func (m *ErrorPassthroughRuleMutation) Field(name string) (ent.Value, bool) {
return m.PassthroughBody()
return m.PassthroughBody()
case errorpassthroughrule.FieldCustomMessage:
case errorpassthroughrule.FieldCustomMessage:
return m.CustomMessage()
return m.CustomMessage()
case errorpassthroughrule.FieldSkipMonitoring:
return m.SkipMonitoring()
case errorpassthroughrule.FieldDescription:
case errorpassthroughrule.FieldDescription:
return m.Description()
return m.Description()
}
}
...
@@ -6702,6 +6744,8 @@ func (m *ErrorPassthroughRuleMutation) OldField(ctx context.Context, name string
...
@@ -6702,6 +6744,8 @@ func (m *ErrorPassthroughRuleMutation) OldField(ctx context.Context, name string
return m.OldPassthroughBody(ctx)
return m.OldPassthroughBody(ctx)
case errorpassthroughrule.FieldCustomMessage:
case errorpassthroughrule.FieldCustomMessage:
return m.OldCustomMessage(ctx)
return m.OldCustomMessage(ctx)
case errorpassthroughrule.FieldSkipMonitoring:
return m.OldSkipMonitoring(ctx)
case errorpassthroughrule.FieldDescription:
case errorpassthroughrule.FieldDescription:
return m.OldDescription(ctx)
return m.OldDescription(ctx)
}
}
...
@@ -6804,6 +6848,13 @@ func (m *ErrorPassthroughRuleMutation) SetField(name string, value ent.Value) er
...
@@ -6804,6 +6848,13 @@ func (m *ErrorPassthroughRuleMutation) SetField(name string, value ent.Value) er
}
}
m.SetCustomMessage(v)
m.SetCustomMessage(v)
return nil
return nil
case errorpassthroughrule.FieldSkipMonitoring:
v, ok := value.(bool)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetSkipMonitoring(v)
return nil
case errorpassthroughrule.FieldDescription:
case errorpassthroughrule.FieldDescription:
v, ok := value.(string)
v, ok := value.(string)
if !ok {
if !ok {
...
@@ -6965,6 +7016,9 @@ func (m *ErrorPassthroughRuleMutation) ResetField(name string) error {
...
@@ -6965,6 +7016,9 @@ func (m *ErrorPassthroughRuleMutation) ResetField(name string) error {
case errorpassthroughrule.FieldCustomMessage:
case errorpassthroughrule.FieldCustomMessage:
m.ResetCustomMessage()
m.ResetCustomMessage()
return nil
return nil
case errorpassthroughrule.FieldSkipMonitoring:
m.ResetSkipMonitoring()
return nil
case errorpassthroughrule.FieldDescription:
case errorpassthroughrule.FieldDescription:
m.ResetDescription()
m.ResetDescription()
return nil
return nil
...
...
backend/ent/runtime/runtime.go
View file @
abf5de69
...
@@ -327,6 +327,10 @@ func init() {
...
@@ -327,6 +327,10 @@ func init() {
errorpassthroughruleDescPassthroughBody
:=
errorpassthroughruleFields
[
9
]
.
Descriptor
()
errorpassthroughruleDescPassthroughBody
:=
errorpassthroughruleFields
[
9
]
.
Descriptor
()
// errorpassthroughrule.DefaultPassthroughBody holds the default value on creation for the passthrough_body field.
// errorpassthroughrule.DefaultPassthroughBody holds the default value on creation for the passthrough_body field.
errorpassthroughrule
.
DefaultPassthroughBody
=
errorpassthroughruleDescPassthroughBody
.
Default
.
(
bool
)
errorpassthroughrule
.
DefaultPassthroughBody
=
errorpassthroughruleDescPassthroughBody
.
Default
.
(
bool
)
// errorpassthroughruleDescSkipMonitoring is the schema descriptor for skip_monitoring field.
errorpassthroughruleDescSkipMonitoring
:=
errorpassthroughruleFields
[
11
]
.
Descriptor
()
// errorpassthroughrule.DefaultSkipMonitoring holds the default value on creation for the skip_monitoring field.
errorpassthroughrule
.
DefaultSkipMonitoring
=
errorpassthroughruleDescSkipMonitoring
.
Default
.
(
bool
)
groupMixin
:=
schema
.
Group
{}
.
Mixin
()
groupMixin
:=
schema
.
Group
{}
.
Mixin
()
groupMixinHooks1
:=
groupMixin
[
1
]
.
Hooks
()
groupMixinHooks1
:=
groupMixin
[
1
]
.
Hooks
()
group
.
Hooks
[
0
]
=
groupMixinHooks1
[
0
]
group
.
Hooks
[
0
]
=
groupMixinHooks1
[
0
]
...
...
backend/ent/schema/error_passthrough_rule.go
View file @
abf5de69
...
@@ -105,6 +105,12 @@ func (ErrorPassthroughRule) Fields() []ent.Field {
...
@@ -105,6 +105,12 @@ func (ErrorPassthroughRule) Fields() []ent.Field {
Optional
()
.
Optional
()
.
Nillable
(),
Nillable
(),
// skip_monitoring: 是否跳过运维监控记录
// true: 匹配此规则的错误不会被记录到 ops_error_logs
// false: 正常记录到运维监控(默认行为)
field
.
Bool
(
"skip_monitoring"
)
.
Default
(
false
),
// description: 规则描述,用于说明规则的用途
// description: 规则描述,用于说明规则的用途
field
.
Text
(
"description"
)
.
field
.
Text
(
"description"
)
.
Optional
()
.
Optional
()
.
...
...
backend/internal/handler/admin/antigravity_oauth_handler.go
View file @
abf5de69
...
@@ -65,3 +65,27 @@ func (h *AntigravityOAuthHandler) ExchangeCode(c *gin.Context) {
...
@@ -65,3 +65,27 @@ func (h *AntigravityOAuthHandler) ExchangeCode(c *gin.Context) {
response
.
Success
(
c
,
tokenInfo
)
response
.
Success
(
c
,
tokenInfo
)
}
}
// AntigravityRefreshTokenRequest represents the request for validating Antigravity refresh token
type
AntigravityRefreshTokenRequest
struct
{
RefreshToken
string
`json:"refresh_token" binding:"required"`
ProxyID
*
int64
`json:"proxy_id"`
}
// RefreshToken validates an Antigravity refresh token and returns full token info
// POST /api/v1/admin/antigravity/oauth/refresh-token
func
(
h
*
AntigravityOAuthHandler
)
RefreshToken
(
c
*
gin
.
Context
)
{
var
req
AntigravityRefreshTokenRequest
if
err
:=
c
.
ShouldBindJSON
(
&
req
);
err
!=
nil
{
response
.
BadRequest
(
c
,
"请求无效: "
+
err
.
Error
())
return
}
tokenInfo
,
err
:=
h
.
antigravityOAuthService
.
ValidateRefreshToken
(
c
.
Request
.
Context
(),
req
.
RefreshToken
,
req
.
ProxyID
)
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
response
.
Success
(
c
,
tokenInfo
)
}
backend/internal/handler/admin/error_passthrough_handler.go
View file @
abf5de69
...
@@ -32,6 +32,7 @@ type CreateErrorPassthroughRuleRequest struct {
...
@@ -32,6 +32,7 @@ type CreateErrorPassthroughRuleRequest struct {
ResponseCode
*
int
`json:"response_code"`
ResponseCode
*
int
`json:"response_code"`
PassthroughBody
*
bool
`json:"passthrough_body"`
PassthroughBody
*
bool
`json:"passthrough_body"`
CustomMessage
*
string
`json:"custom_message"`
CustomMessage
*
string
`json:"custom_message"`
SkipMonitoring
*
bool
`json:"skip_monitoring"`
Description
*
string
`json:"description"`
Description
*
string
`json:"description"`
}
}
...
@@ -48,6 +49,7 @@ type UpdateErrorPassthroughRuleRequest struct {
...
@@ -48,6 +49,7 @@ type UpdateErrorPassthroughRuleRequest struct {
ResponseCode
*
int
`json:"response_code"`
ResponseCode
*
int
`json:"response_code"`
PassthroughBody
*
bool
`json:"passthrough_body"`
PassthroughBody
*
bool
`json:"passthrough_body"`
CustomMessage
*
string
`json:"custom_message"`
CustomMessage
*
string
`json:"custom_message"`
SkipMonitoring
*
bool
`json:"skip_monitoring"`
Description
*
string
`json:"description"`
Description
*
string
`json:"description"`
}
}
...
@@ -122,6 +124,9 @@ func (h *ErrorPassthroughHandler) Create(c *gin.Context) {
...
@@ -122,6 +124,9 @@ func (h *ErrorPassthroughHandler) Create(c *gin.Context) {
}
else
{
}
else
{
rule
.
PassthroughBody
=
true
rule
.
PassthroughBody
=
true
}
}
if
req
.
SkipMonitoring
!=
nil
{
rule
.
SkipMonitoring
=
*
req
.
SkipMonitoring
}
rule
.
ResponseCode
=
req
.
ResponseCode
rule
.
ResponseCode
=
req
.
ResponseCode
rule
.
CustomMessage
=
req
.
CustomMessage
rule
.
CustomMessage
=
req
.
CustomMessage
rule
.
Description
=
req
.
Description
rule
.
Description
=
req
.
Description
...
@@ -190,6 +195,7 @@ func (h *ErrorPassthroughHandler) Update(c *gin.Context) {
...
@@ -190,6 +195,7 @@ func (h *ErrorPassthroughHandler) Update(c *gin.Context) {
ResponseCode
:
existing
.
ResponseCode
,
ResponseCode
:
existing
.
ResponseCode
,
PassthroughBody
:
existing
.
PassthroughBody
,
PassthroughBody
:
existing
.
PassthroughBody
,
CustomMessage
:
existing
.
CustomMessage
,
CustomMessage
:
existing
.
CustomMessage
,
SkipMonitoring
:
existing
.
SkipMonitoring
,
Description
:
existing
.
Description
,
Description
:
existing
.
Description
,
}
}
...
@@ -230,6 +236,9 @@ func (h *ErrorPassthroughHandler) Update(c *gin.Context) {
...
@@ -230,6 +236,9 @@ func (h *ErrorPassthroughHandler) Update(c *gin.Context) {
if
req
.
Description
!=
nil
{
if
req
.
Description
!=
nil
{
rule
.
Description
=
req
.
Description
rule
.
Description
=
req
.
Description
}
}
if
req
.
SkipMonitoring
!=
nil
{
rule
.
SkipMonitoring
=
*
req
.
SkipMonitoring
}
// 确保切片不为 nil
// 确保切片不为 nil
if
rule
.
ErrorCodes
==
nil
{
if
rule
.
ErrorCodes
==
nil
{
...
...
backend/internal/handler/admin/redeem_handler.go
View file @
abf5de69
...
@@ -202,7 +202,7 @@ func (h *RedeemHandler) Export(c *gin.Context) {
...
@@ -202,7 +202,7 @@ func (h *RedeemHandler) Export(c *gin.Context) {
writer
:=
csv
.
NewWriter
(
&
buf
)
writer
:=
csv
.
NewWriter
(
&
buf
)
// Write header
// Write header
if
err
:=
writer
.
Write
([]
string
{
"id"
,
"code"
,
"type"
,
"value"
,
"status"
,
"used_by"
,
"used_at"
,
"created_at"
});
err
!=
nil
{
if
err
:=
writer
.
Write
([]
string
{
"id"
,
"code"
,
"type"
,
"value"
,
"status"
,
"used_by"
,
"used_by_email"
,
"used_at"
,
"created_at"
});
err
!=
nil
{
response
.
InternalError
(
c
,
"Failed to export redeem codes: "
+
err
.
Error
())
response
.
InternalError
(
c
,
"Failed to export redeem codes: "
+
err
.
Error
())
return
return
}
}
...
@@ -213,6 +213,10 @@ func (h *RedeemHandler) Export(c *gin.Context) {
...
@@ -213,6 +213,10 @@ func (h *RedeemHandler) Export(c *gin.Context) {
if
code
.
UsedBy
!=
nil
{
if
code
.
UsedBy
!=
nil
{
usedBy
=
fmt
.
Sprintf
(
"%d"
,
*
code
.
UsedBy
)
usedBy
=
fmt
.
Sprintf
(
"%d"
,
*
code
.
UsedBy
)
}
}
usedByEmail
:=
""
if
code
.
User
!=
nil
{
usedByEmail
=
code
.
User
.
Email
}
usedAt
:=
""
usedAt
:=
""
if
code
.
UsedAt
!=
nil
{
if
code
.
UsedAt
!=
nil
{
usedAt
=
code
.
UsedAt
.
Format
(
"2006-01-02 15:04:05"
)
usedAt
=
code
.
UsedAt
.
Format
(
"2006-01-02 15:04:05"
)
...
@@ -224,6 +228,7 @@ func (h *RedeemHandler) Export(c *gin.Context) {
...
@@ -224,6 +228,7 @@ func (h *RedeemHandler) Export(c *gin.Context) {
fmt
.
Sprintf
(
"%.2f"
,
code
.
Value
),
fmt
.
Sprintf
(
"%.2f"
,
code
.
Value
),
code
.
Status
,
code
.
Status
,
usedBy
,
usedBy
,
usedByEmail
,
usedAt
,
usedAt
,
code
.
CreatedAt
.
Format
(
"2006-01-02 15:04:05"
),
code
.
CreatedAt
.
Format
(
"2006-01-02 15:04:05"
),
});
err
!=
nil
{
});
err
!=
nil
{
...
...
backend/internal/handler/gateway_handler.go
View file @
abf5de69
...
@@ -7,6 +7,7 @@ import (
...
@@ -7,6 +7,7 @@ import (
"errors"
"errors"
"fmt"
"fmt"
"io"
"io"
"log"
"net/http"
"net/http"
"strings"
"strings"
"time"
"time"
...
@@ -247,6 +248,7 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
...
@@ -247,6 +248,7 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
maxAccountSwitches
:=
h
.
maxAccountSwitchesGemini
maxAccountSwitches
:=
h
.
maxAccountSwitchesGemini
switchCount
:=
0
switchCount
:=
0
failedAccountIDs
:=
make
(
map
[
int64
]
struct
{})
failedAccountIDs
:=
make
(
map
[
int64
]
struct
{})
sameAccountRetryCount
:=
make
(
map
[
int64
]
int
)
// 同账号重试计数
var
lastFailoverErr
*
service
.
UpstreamFailoverError
var
lastFailoverErr
*
service
.
UpstreamFailoverError
var
forceCacheBilling
bool
// 粘性会话切换时的缓存计费标记
var
forceCacheBilling
bool
// 粘性会话切换时的缓存计费标记
...
@@ -376,11 +378,28 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
...
@@ -376,11 +378,28 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
if
err
!=
nil
{
if
err
!=
nil
{
var
failoverErr
*
service
.
UpstreamFailoverError
var
failoverErr
*
service
.
UpstreamFailoverError
if
errors
.
As
(
err
,
&
failoverErr
)
{
if
errors
.
As
(
err
,
&
failoverErr
)
{
failedAccountIDs
[
account
.
ID
]
=
struct
{}{}
lastFailoverErr
=
failoverErr
lastFailoverErr
=
failoverErr
if
needForceCacheBilling
(
hasBoundSession
,
failoverErr
)
{
if
needForceCacheBilling
(
hasBoundSession
,
failoverErr
)
{
forceCacheBilling
=
true
forceCacheBilling
=
true
}
}
// 同账号重试:对 RetryableOnSameAccount 的临时性错误,先在同一账号上重试
if
failoverErr
.
RetryableOnSameAccount
&&
sameAccountRetryCount
[
account
.
ID
]
<
maxSameAccountRetries
{
sameAccountRetryCount
[
account
.
ID
]
++
log
.
Printf
(
"Account %d: retryable error %d, same-account retry %d/%d"
,
account
.
ID
,
failoverErr
.
StatusCode
,
sameAccountRetryCount
[
account
.
ID
],
maxSameAccountRetries
)
if
!
sleepSameAccountRetryDelay
(
c
.
Request
.
Context
())
{
return
}
continue
}
// 同账号重试用尽,执行临时封禁并切换账号
if
failoverErr
.
RetryableOnSameAccount
{
h
.
gatewayService
.
TempUnscheduleRetryableError
(
c
.
Request
.
Context
(),
account
.
ID
,
failoverErr
)
}
failedAccountIDs
[
account
.
ID
]
=
struct
{}{}
if
switchCount
>=
maxAccountSwitches
{
if
switchCount
>=
maxAccountSwitches
{
h
.
handleFailoverExhausted
(
c
,
failoverErr
,
service
.
PlatformGemini
,
streamStarted
)
h
.
handleFailoverExhausted
(
c
,
failoverErr
,
service
.
PlatformGemini
,
streamStarted
)
return
return
...
@@ -456,6 +475,7 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
...
@@ -456,6 +475,7 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
maxAccountSwitches
:=
h
.
maxAccountSwitches
maxAccountSwitches
:=
h
.
maxAccountSwitches
switchCount
:=
0
switchCount
:=
0
failedAccountIDs
:=
make
(
map
[
int64
]
struct
{})
failedAccountIDs
:=
make
(
map
[
int64
]
struct
{})
sameAccountRetryCount
:=
make
(
map
[
int64
]
int
)
// 同账号重试计数
var
lastFailoverErr
*
service
.
UpstreamFailoverError
var
lastFailoverErr
*
service
.
UpstreamFailoverError
retryWithFallback
:=
false
retryWithFallback
:=
false
var
forceCacheBilling
bool
// 粘性会话切换时的缓存计费标记
var
forceCacheBilling
bool
// 粘性会话切换时的缓存计费标记
...
@@ -623,11 +643,28 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
...
@@ -623,11 +643,28 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
}
}
var
failoverErr
*
service
.
UpstreamFailoverError
var
failoverErr
*
service
.
UpstreamFailoverError
if
errors
.
As
(
err
,
&
failoverErr
)
{
if
errors
.
As
(
err
,
&
failoverErr
)
{
failedAccountIDs
[
account
.
ID
]
=
struct
{}{}
lastFailoverErr
=
failoverErr
lastFailoverErr
=
failoverErr
if
needForceCacheBilling
(
hasBoundSession
,
failoverErr
)
{
if
needForceCacheBilling
(
hasBoundSession
,
failoverErr
)
{
forceCacheBilling
=
true
forceCacheBilling
=
true
}
}
// 同账号重试:对 RetryableOnSameAccount 的临时性错误,先在同一账号上重试
if
failoverErr
.
RetryableOnSameAccount
&&
sameAccountRetryCount
[
account
.
ID
]
<
maxSameAccountRetries
{
sameAccountRetryCount
[
account
.
ID
]
++
log
.
Printf
(
"Account %d: retryable error %d, same-account retry %d/%d"
,
account
.
ID
,
failoverErr
.
StatusCode
,
sameAccountRetryCount
[
account
.
ID
],
maxSameAccountRetries
)
if
!
sleepSameAccountRetryDelay
(
c
.
Request
.
Context
())
{
return
}
continue
}
// 同账号重试用尽,执行临时封禁并切换账号
if
failoverErr
.
RetryableOnSameAccount
{
h
.
gatewayService
.
TempUnscheduleRetryableError
(
c
.
Request
.
Context
(),
account
.
ID
,
failoverErr
)
}
failedAccountIDs
[
account
.
ID
]
=
struct
{}{}
if
switchCount
>=
maxAccountSwitches
{
if
switchCount
>=
maxAccountSwitches
{
h
.
handleFailoverExhausted
(
c
,
failoverErr
,
account
.
Platform
,
streamStarted
)
h
.
handleFailoverExhausted
(
c
,
failoverErr
,
account
.
Platform
,
streamStarted
)
return
return
...
@@ -935,6 +972,23 @@ func needForceCacheBilling(hasBoundSession bool, failoverErr *service.UpstreamFa
...
@@ -935,6 +972,23 @@ func needForceCacheBilling(hasBoundSession bool, failoverErr *service.UpstreamFa
return
hasBoundSession
||
(
failoverErr
!=
nil
&&
failoverErr
.
ForceCacheBilling
)
return
hasBoundSession
||
(
failoverErr
!=
nil
&&
failoverErr
.
ForceCacheBilling
)
}
}
const
(
// maxSameAccountRetries 同账号重试次数上限(针对 RetryableOnSameAccount 错误)
maxSameAccountRetries
=
2
// sameAccountRetryDelay 同账号重试间隔
sameAccountRetryDelay
=
500
*
time
.
Millisecond
)
// sleepSameAccountRetryDelay 同账号重试固定延时,返回 false 表示 context 已取消。
func
sleepSameAccountRetryDelay
(
ctx
context
.
Context
)
bool
{
select
{
case
<-
ctx
.
Done
()
:
return
false
case
<-
time
.
After
(
sameAccountRetryDelay
)
:
return
true
}
}
// sleepFailoverDelay 账号切换线性递增延时:第1次0s、第2次1s、第3次2s…
// sleepFailoverDelay 账号切换线性递增延时:第1次0s、第2次1s、第3次2s…
// 返回 false 表示 context 已取消。
// 返回 false 表示 context 已取消。
func
sleepFailoverDelay
(
ctx
context
.
Context
,
switchCount
int
)
bool
{
func
sleepFailoverDelay
(
ctx
context
.
Context
,
switchCount
int
)
bool
{
...
@@ -994,6 +1048,10 @@ func (h *GatewayHandler) handleFailoverExhausted(c *gin.Context, failoverErr *se
...
@@ -994,6 +1048,10 @@ func (h *GatewayHandler) handleFailoverExhausted(c *gin.Context, failoverErr *se
msg
=
*
rule
.
CustomMessage
msg
=
*
rule
.
CustomMessage
}
}
if
rule
.
SkipMonitoring
{
c
.
Set
(
service
.
OpsSkipPassthroughKey
,
true
)
}
h
.
handleStreamingAwareError
(
c
,
respCode
,
"upstream_error"
,
msg
,
streamStarted
)
h
.
handleStreamingAwareError
(
c
,
respCode
,
"upstream_error"
,
msg
,
streamStarted
)
return
return
}
}
...
...
backend/internal/handler/gemini_v1beta_handler.go
View file @
abf5de69
...
@@ -598,6 +598,10 @@ func (h *GatewayHandler) handleGeminiFailoverExhausted(c *gin.Context, failoverE
...
@@ -598,6 +598,10 @@ func (h *GatewayHandler) handleGeminiFailoverExhausted(c *gin.Context, failoverE
msg
=
*
rule
.
CustomMessage
msg
=
*
rule
.
CustomMessage
}
}
if
rule
.
SkipMonitoring
{
c
.
Set
(
service
.
OpsSkipPassthroughKey
,
true
)
}
googleError
(
c
,
respCode
,
msg
)
googleError
(
c
,
respCode
,
msg
)
return
return
}
}
...
...
backend/internal/handler/openai_gateway_handler.go
View file @
abf5de69
...
@@ -453,6 +453,10 @@ func (h *OpenAIGatewayHandler) handleFailoverExhausted(c *gin.Context, failoverE
...
@@ -453,6 +453,10 @@ func (h *OpenAIGatewayHandler) handleFailoverExhausted(c *gin.Context, failoverE
msg
=
*
rule
.
CustomMessage
msg
=
*
rule
.
CustomMessage
}
}
if
rule
.
SkipMonitoring
{
c
.
Set
(
service
.
OpsSkipPassthroughKey
,
true
)
}
h
.
handleStreamingAwareError
(
c
,
respCode
,
"upstream_error"
,
msg
,
streamStarted
)
h
.
handleStreamingAwareError
(
c
,
respCode
,
"upstream_error"
,
msg
,
streamStarted
)
return
return
}
}
...
...
backend/internal/handler/ops_error_logger.go
View file @
abf5de69
...
@@ -553,6 +553,13 @@ func OpsErrorLoggerMiddleware(ops *service.OpsService) gin.HandlerFunc {
...
@@ -553,6 +553,13 @@ func OpsErrorLoggerMiddleware(ops *service.OpsService) gin.HandlerFunc {
// Store request headers/body only when an upstream error occurred to keep overhead minimal.
// Store request headers/body only when an upstream error occurred to keep overhead minimal.
entry
.
RequestHeadersJSON
=
extractOpsRetryRequestHeaders
(
c
)
entry
.
RequestHeadersJSON
=
extractOpsRetryRequestHeaders
(
c
)
// Skip logging if a passthrough rule with skip_monitoring=true matched.
if
v
,
ok
:=
c
.
Get
(
service
.
OpsSkipPassthroughKey
);
ok
{
if
skip
,
_
:=
v
.
(
bool
);
skip
{
return
}
}
enqueueOpsErrorLog
(
ops
,
entry
,
requestBody
)
enqueueOpsErrorLog
(
ops
,
entry
,
requestBody
)
return
return
}
}
...
@@ -560,6 +567,13 @@ func OpsErrorLoggerMiddleware(ops *service.OpsService) gin.HandlerFunc {
...
@@ -560,6 +567,13 @@ func OpsErrorLoggerMiddleware(ops *service.OpsService) gin.HandlerFunc {
body
:=
w
.
buf
.
Bytes
()
body
:=
w
.
buf
.
Bytes
()
parsed
:=
parseOpsErrorResponse
(
body
)
parsed
:=
parseOpsErrorResponse
(
body
)
// Skip logging if a passthrough rule with skip_monitoring=true matched.
if
v
,
ok
:=
c
.
Get
(
service
.
OpsSkipPassthroughKey
);
ok
{
if
skip
,
_
:=
v
.
(
bool
);
skip
{
return
}
}
// Skip logging if the error should be filtered based on settings
// Skip logging if the error should be filtered based on settings
if
shouldSkipOpsErrorLog
(
c
.
Request
.
Context
(),
ops
,
parsed
.
Message
,
string
(
body
),
c
.
Request
.
URL
.
Path
)
{
if
shouldSkipOpsErrorLog
(
c
.
Request
.
Context
(),
ops
,
parsed
.
Message
,
string
(
body
),
c
.
Request
.
URL
.
Path
)
{
return
return
...
...
backend/internal/model/error_passthrough_rule.go
View file @
abf5de69
...
@@ -18,6 +18,7 @@ type ErrorPassthroughRule struct {
...
@@ -18,6 +18,7 @@ type ErrorPassthroughRule struct {
ResponseCode
*
int
`json:"response_code"`
// 自定义状态码(passthrough_code=false 时使用)
ResponseCode
*
int
`json:"response_code"`
// 自定义状态码(passthrough_code=false 时使用)
PassthroughBody
bool
`json:"passthrough_body"`
// 是否透传原始错误信息
PassthroughBody
bool
`json:"passthrough_body"`
// 是否透传原始错误信息
CustomMessage
*
string
`json:"custom_message"`
// 自定义错误信息(passthrough_body=false 时使用)
CustomMessage
*
string
`json:"custom_message"`
// 自定义错误信息(passthrough_body=false 时使用)
SkipMonitoring
bool
`json:"skip_monitoring"`
// 是否跳过运维监控记录
Description
*
string
`json:"description"`
// 规则描述
Description
*
string
`json:"description"`
// 规则描述
CreatedAt
time
.
Time
`json:"created_at"`
CreatedAt
time
.
Time
`json:"created_at"`
UpdatedAt
time
.
Time
`json:"updated_at"`
UpdatedAt
time
.
Time
`json:"updated_at"`
...
...
backend/internal/pkg/antigravity/claude_types.go
View file @
abf5de69
...
@@ -27,7 +27,7 @@ type ClaudeMessage struct {
...
@@ -27,7 +27,7 @@ type ClaudeMessage struct {
// ThinkingConfig Thinking 配置
// ThinkingConfig Thinking 配置
type
ThinkingConfig
struct
{
type
ThinkingConfig
struct
{
Type
string
`json:"type"`
// "enabled"
or
"disabled"
Type
string
`json:"type"`
// "enabled"
/ "adaptive" /
"disabled"
BudgetTokens
int
`json:"budget_tokens,omitempty"`
// thinking budget
BudgetTokens
int
`json:"budget_tokens,omitempty"`
// thinking budget
}
}
...
...
backend/internal/pkg/antigravity/client.go
View file @
abf5de69
...
@@ -115,6 +115,23 @@ type LoadCodeAssistResponse struct {
...
@@ -115,6 +115,23 @@ type LoadCodeAssistResponse struct {
IneligibleTiers
[]
*
IneligibleTier
`json:"ineligibleTiers,omitempty"`
IneligibleTiers
[]
*
IneligibleTier
`json:"ineligibleTiers,omitempty"`
}
}
// OnboardUserRequest onboardUser 请求
type
OnboardUserRequest
struct
{
TierID
string
`json:"tierId"`
Metadata
struct
{
IDEType
string
`json:"ideType"`
Platform
string
`json:"platform,omitempty"`
PluginType
string
`json:"pluginType,omitempty"`
}
`json:"metadata"`
}
// OnboardUserResponse onboardUser 响应
type
OnboardUserResponse
struct
{
Name
string
`json:"name,omitempty"`
Done
bool
`json:"done"`
Response
map
[
string
]
any
`json:"response,omitempty"`
}
// GetTier 获取账户类型
// GetTier 获取账户类型
// 优先返回 paidTier(付费订阅级别),否则返回 currentTier
// 优先返回 paidTier(付费订阅级别),否则返回 currentTier
func
(
r
*
LoadCodeAssistResponse
)
GetTier
()
string
{
func
(
r
*
LoadCodeAssistResponse
)
GetTier
()
string
{
...
@@ -371,6 +388,117 @@ func (c *Client) LoadCodeAssist(ctx context.Context, accessToken string) (*LoadC
...
@@ -371,6 +388,117 @@ func (c *Client) LoadCodeAssist(ctx context.Context, accessToken string) (*LoadC
return
nil
,
nil
,
lastErr
return
nil
,
nil
,
lastErr
}
}
// OnboardUser 触发账号 onboarding,并返回 project_id
// 说明:
// 1) 部分账号 loadCodeAssist 不会立即返回 cloudaicompanionProject;
// 2) 这时需要调用 onboardUser 完成初始化,之后才能拿到 project_id。
func
(
c
*
Client
)
OnboardUser
(
ctx
context
.
Context
,
accessToken
,
tierID
string
)
(
string
,
error
)
{
tierID
=
strings
.
TrimSpace
(
tierID
)
if
tierID
==
""
{
return
""
,
fmt
.
Errorf
(
"tier_id 为空"
)
}
reqBody
:=
OnboardUserRequest
{
TierID
:
tierID
}
reqBody
.
Metadata
.
IDEType
=
"ANTIGRAVITY"
reqBody
.
Metadata
.
Platform
=
"PLATFORM_UNSPECIFIED"
reqBody
.
Metadata
.
PluginType
=
"GEMINI"
bodyBytes
,
err
:=
json
.
Marshal
(
reqBody
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"序列化请求失败: %w"
,
err
)
}
availableURLs
:=
BaseURLs
var
lastErr
error
for
urlIdx
,
baseURL
:=
range
availableURLs
{
apiURL
:=
baseURL
+
"/v1internal:onboardUser"
for
attempt
:=
1
;
attempt
<=
5
;
attempt
++
{
req
,
err
:=
http
.
NewRequestWithContext
(
ctx
,
http
.
MethodPost
,
apiURL
,
bytes
.
NewReader
(
bodyBytes
))
if
err
!=
nil
{
lastErr
=
fmt
.
Errorf
(
"创建请求失败: %w"
,
err
)
break
}
req
.
Header
.
Set
(
"Authorization"
,
"Bearer "
+
accessToken
)
req
.
Header
.
Set
(
"Content-Type"
,
"application/json"
)
req
.
Header
.
Set
(
"User-Agent"
,
UserAgent
)
resp
,
err
:=
c
.
httpClient
.
Do
(
req
)
if
err
!=
nil
{
lastErr
=
fmt
.
Errorf
(
"onboardUser 请求失败: %w"
,
err
)
if
shouldFallbackToNextURL
(
err
,
0
)
&&
urlIdx
<
len
(
availableURLs
)
-
1
{
log
.
Printf
(
"[antigravity] onboardUser URL fallback: %s -> %s"
,
baseURL
,
availableURLs
[
urlIdx
+
1
])
break
}
return
""
,
lastErr
}
respBodyBytes
,
err
:=
io
.
ReadAll
(
resp
.
Body
)
_
=
resp
.
Body
.
Close
()
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"读取响应失败: %w"
,
err
)
}
if
shouldFallbackToNextURL
(
nil
,
resp
.
StatusCode
)
&&
urlIdx
<
len
(
availableURLs
)
-
1
{
log
.
Printf
(
"[antigravity] onboardUser URL fallback (HTTP %d): %s -> %s"
,
resp
.
StatusCode
,
baseURL
,
availableURLs
[
urlIdx
+
1
])
break
}
if
resp
.
StatusCode
!=
http
.
StatusOK
{
lastErr
=
fmt
.
Errorf
(
"onboardUser 失败 (HTTP %d): %s"
,
resp
.
StatusCode
,
string
(
respBodyBytes
))
return
""
,
lastErr
}
var
onboardResp
OnboardUserResponse
if
err
:=
json
.
Unmarshal
(
respBodyBytes
,
&
onboardResp
);
err
!=
nil
{
lastErr
=
fmt
.
Errorf
(
"onboardUser 响应解析失败: %w"
,
err
)
return
""
,
lastErr
}
if
onboardResp
.
Done
{
if
projectID
:=
extractProjectIDFromOnboardResponse
(
onboardResp
.
Response
);
projectID
!=
""
{
DefaultURLAvailability
.
MarkSuccess
(
baseURL
)
return
projectID
,
nil
}
lastErr
=
fmt
.
Errorf
(
"onboardUser 完成但未返回 project_id"
)
return
""
,
lastErr
}
// done=false 时等待后重试(与 CLIProxyAPI 行为一致)
select
{
case
<-
time
.
After
(
2
*
time
.
Second
)
:
case
<-
ctx
.
Done
()
:
return
""
,
ctx
.
Err
()
}
}
}
if
lastErr
!=
nil
{
return
""
,
lastErr
}
return
""
,
fmt
.
Errorf
(
"onboardUser 未返回 project_id"
)
}
func
extractProjectIDFromOnboardResponse
(
resp
map
[
string
]
any
)
string
{
if
len
(
resp
)
==
0
{
return
""
}
if
v
,
ok
:=
resp
[
"cloudaicompanionProject"
];
ok
{
switch
project
:=
v
.
(
type
)
{
case
string
:
return
strings
.
TrimSpace
(
project
)
case
map
[
string
]
any
:
if
id
,
ok
:=
project
[
"id"
]
.
(
string
);
ok
{
return
strings
.
TrimSpace
(
id
)
}
}
}
return
""
}
// ModelQuotaInfo 模型配额信息
// ModelQuotaInfo 模型配额信息
type
ModelQuotaInfo
struct
{
type
ModelQuotaInfo
struct
{
RemainingFraction
float64
`json:"remainingFraction"`
RemainingFraction
float64
`json:"remainingFraction"`
...
...
backend/internal/pkg/antigravity/client_test.go
View file @
abf5de69
...
@@ -1655,3 +1655,74 @@ func TestClient_FetchAvailableModels_404Fallback_RealCall(t *testing.T) {
...
@@ -1655,3 +1655,74 @@ func TestClient_FetchAvailableModels_404Fallback_RealCall(t *testing.T) {
t
.
Error
(
"应返回 fallback server 的模型 m1"
)
t
.
Error
(
"应返回 fallback server 的模型 m1"
)
}
}
}
}
func
TestExtractProjectIDFromOnboardResponse
(
t
*
testing
.
T
)
{
t
.
Parallel
()
tests
:=
[]
struct
{
name
string
resp
map
[
string
]
any
want
string
}{
{
name
:
"nil response"
,
resp
:
nil
,
want
:
""
,
},
{
name
:
"empty response"
,
resp
:
map
[
string
]
any
{},
want
:
""
,
},
{
name
:
"project as string"
,
resp
:
map
[
string
]
any
{
"cloudaicompanionProject"
:
"my-project-123"
,
},
want
:
"my-project-123"
,
},
{
name
:
"project as string with spaces"
,
resp
:
map
[
string
]
any
{
"cloudaicompanionProject"
:
" my-project-123 "
,
},
want
:
"my-project-123"
,
},
{
name
:
"project as map with id"
,
resp
:
map
[
string
]
any
{
"cloudaicompanionProject"
:
map
[
string
]
any
{
"id"
:
"proj-from-map"
,
},
},
want
:
"proj-from-map"
,
},
{
name
:
"project as map without id"
,
resp
:
map
[
string
]
any
{
"cloudaicompanionProject"
:
map
[
string
]
any
{
"name"
:
"some-name"
,
},
},
want
:
""
,
},
{
name
:
"missing cloudaicompanionProject key"
,
resp
:
map
[
string
]
any
{
"otherField"
:
"value"
,
},
want
:
""
,
},
}
for
_
,
tc
:=
range
tests
{
t
.
Run
(
tc
.
name
,
func
(
t
*
testing
.
T
)
{
t
.
Parallel
()
got
:=
extractProjectIDFromOnboardResponse
(
tc
.
resp
)
if
got
!=
tc
.
want
{
t
.
Fatalf
(
"extractProjectIDFromOnboardResponse() = %q, want %q"
,
got
,
tc
.
want
)
}
})
}
}
Prev
1
2
3
4
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment