"culprit" deprecated - in favor of what?


#1

The manual page on optional attributes says about the culprit attribute:

The name of the culprit which caused this exception. This attribute is deprecated.

It doesn’t explain why.

I can’t find anything, not in the change-logs and not in the actual source-code, that indicates this attribute was deprecated, or when, or why.

What’s more, this value is actually being used in the current (hosted) version of Sentry.

Here:

Is it really deprecated?

In favor of what? What’s the alternative?

It seems different values go into that particular field on the page, depending on which values are available in a submitted Event - what exactly goes into this field, and when, and why?


#2

New users are only allowed to post one image (!?) so here’s another:


#3

It also clealy hasn’t been removed from Sentry’s internal model:


#4

The replacement is right above culprit in the docs and it’s called:

transaction:

The name of the transaction which caused this exception
For example, in a web app, this might be the route name: /welcome/

{
  "transaction": "/users/<username>/"
}

#5

@bruno-garcia I’m sorry, but that’s nowhere near close to the description of culprit, not is that how it’s implemented in neither the 1.x or 2.x versions of the PHP client.

I could just put the path and function-name in that field, of course - and have it display where I want, but from the description, that’s not at all what this is for?


#6

@mindplay-dk transaction and culprint are extremely similar. Older versions of Sentry will in fact set the transaction to the culprit if the transaction is missing. In the most recent version on master it is almost the other way around: if a client sends the transaction, it is used as culprit. What you were highlighting in the OP’s screenshot is internally still called culprit (and that’s why you see it in the JSON download from sentry.io), but SDKs are no longer supposed to send it directly (I don’t know enough about the PHP SDK, but it definetly needs some work in general).

A transaction can be both a route name or a function name.

  • Route names are often used because that’s usually what web devs associate with their views.
  • If you have completely different code branches behind a single route (because you are building some kind of RPC interface over HTTP, for example), it might make more sense to use something else than the route name.

Can you elaborate why you think the descriptions in the docs are not similar?

The name of the culprit which caused this exception

vs

The name of the transaction which caused this exception


#7

Can you elaborate why you think the descriptions in the docs are not similar?

I meant in relation to the PHP client, which defines the “culprit” as the filename and function-name where this failed - which is what I’d like to see next to an Exception message in the page header in Sentry.

This new field is supposed to describe a “transaction”, which to me implies a description of what initiated the error - as, for example, the example given, an application-dependent route-name. (It’s not the route that fails, it’s something in the code-path that gets dispatched by that route.)

Contrast with the old field, which typically described where or by what the error was triggered. The “culprit”, the thing that triggered the error, not what initiated the code-path that lead to that error.

Can you see the difference? What failed vs what lead to the failure.

I personally have a hard time seeing how that fits with the description, the example, or the term “transaction”.

Maybe that’s just me.


#8

Could you show me where the PHP SDK defines culprit like that? It definetly isn’t intended to work that way although often practically it does turn out to be like this because we don’t have any better data. This is why transactions exist now.


#9

Yeah, that’s probably the explanation I was looking for - you’re probably right, I don’t think the client explicitly submits the information that way, it’s just how it ends up.

Either way, I still don’t feel like there’s a natural place to put the error/exception description and location? And if I put that in the “transaction” field, I’ll have to put route information somewhere else.

(To be honest, I wish the server didn’t apply any logic or transformations to the incoming data at all - it would make the clients much more explicit and easier to understand. Currently, there is a lot of hidden logic and “hidden reasons” why information ends up in particular fields, why an Event ends up with certain tags, and so on…)


#10

We absolutely feel the same way, at the same time we can’t remove the logic for SDKs that already rely on it. The worst-case scenario when touching event processing in Sentry is that the code after processing the event recognizes the event as a separate new group and blasts out a bunch of false-positive notifications because it thinks it got a new kind of error.

There’s a bunch of heuristics in Sentry for finding the culprit, but if you set transaction in your events, they will appear as culprit and bypass that code entirely.


#11

There’s a bunch of heuristics in Sentry for finding the culprit, but if you set transaction in your events, they will appear as culprit and bypass that code entirely.

Okay, good, that at least gives the client the ability to override the built-in decision-making :slight_smile:

I’m still unsure what to put in the transaction field though, because not all transactions are web transactions - we have apps running under the console as well, where there’s no router, no request context, and therefore no route.

While it would be nice to have the web-route display prominently, I think I will have to just to put file-name and line-number in the transaction field, because those are available for every error.

I guess I’ll put the web-route in a tag instead.


#12

You can totally use the route name for web transactions. and the name of the command + subcommand for the CLI. At least that’s how I would do it.

For example the Python SDK uses the celery task name (a function name) for transactions happening in the Celery job queue and route names in Django for the web transactions.