Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.Data.SqlClient.SqlException: String or binary data would be truncated in table 'Umbraco.dbo.umbracoLog', #9458

Closed
kimschurmann opened this issue Nov 26, 2020 · 32 comments

Comments

@kimschurmann
Copy link

kimschurmann commented Nov 26, 2020

We have added a custom component that creates and saves pages on all languages that have english as fallback, to help the editor create default pages. But occasionally this fails with an audit log.

Here is the stack trace:

System.Data.SqlClient.SqlException: String or binary data would be truncated in table 'Umbraco.dbo.umbracoLog', column 'parameters'. Truncated value: 'English (United Kingdom), English, Spanish (Spain), Estonian (Estonia), Finnish (Finland), French (B'. The statement has been terminated.

Stacktrace

at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)

   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)

   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)

   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()

   at System.Data.SqlClient.SqlDataReader.get_MetaData()

   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)

   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)

   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)

   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)

   at System.Data.SqlClient.SqlCommand.ExecuteScalar()

   at Umbraco.Core.Persistence.FaultHandling.RetryPolicy.ExecuteAction[TResult](Func`1 func)

   at NPoco.Database.ExecuteScalarHelper(DbCommand cmd)

   at NPoco.Database.InsertImp[T](PocoData pocoData, String tableName, String primaryKeyName, Boolean autoIncrement, T poco)

   at NPoco.Database.Insert[T](String tableName, String primaryKeyName, Boolean autoIncrement, T poco)

   at NPoco.Database.Insert[T](T poco)

   at Umbraco.Core.Persistence.Repositories.Implement.AuditRepository.PersistUpdatedItem(IAuditItem entity)

   at Umbraco.Core.Services.Implement.ContentService.Save(IContent content, Int32 userId, Boolean raiseEvents)

   at Umbraco.Web.Editors.ContentController.SaveAndNotify(ContentItemSave contentItem, Func`2 saveMethod, Int32 variantCount, Dictionary`2 notifications, SimpleNotificationModel globalNotifications, String invariantSavedLocalizationKey, String variantSavedLocalizationKey, String cultureForInvariantErrors, Boolean& wasCancelled)

   at Umbraco.Web.Editors.ContentController.PostSaveInternal(ContentItemSave contentItem, Func`2 saveMethod, Func`2 mapToDisplay)

   at lambda_method(Closure , Object , Object[] )

   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_2.<GetExecutor>b__2(Object instance, Object[] methodParameters)

   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()

Umbraco version

I am seeing this issue on Umbraco version: 8.5.5

Reproduction

Create a website with a lot of langauges that fallback to English. Add this component and try to save a new english page.

Here is the custom component:

public class CustomEditorComponent : IComponent
    {
        private readonly ILocalizationService _localizationService;

        public CustomEditorComponent(ILocalizationService localizationService)
        {
            _localizationService = localizationService;
        }

        public void Initialize()
        {
            ContentService.Saving += ContentServiceOnSaving;
        }

        public void Terminate()
        {

        }

        private void ContentServiceOnSaving(IContentService sender, ContentSavingEventArgs args)
        {
            string defaultLanguageIso = _localizationService.GetDefaultLanguageIsoCode();
            string[] englishFallbackLanguages = _localizationService.GetAllLanguages()
                .Select(l => l.CultureInfo.Name)
                .ToArray();

            foreach (IContent content in args.SavedEntities)
            {
                if (content.ContentType.VariesByCulture() && args.IsSavingCulture(content, defaultLanguageIso))
                {
                    string defaultName = content.GetCultureName(defaultLanguageIso);
                    foreach (string culture in englishFallbackLanguages)
                    {
                        if (string.IsNullOrWhiteSpace(content.GetCultureName(culture)))
                        {
                            content.SetCultureName(defaultName, culture);
                        }
                    }
                }
            }
        }
    }

Bug summary

Specifics

Steps to reproduce

Expected result

Actual result


This item has been added to our backlog AB#9875

@nul800sebastiaan
Copy link
Member

Looks like something is a bit too long when this method gets called https://github.com/umbraco/Umbraco-CMS/blame/v8/contrib/src/Umbraco.Core/Persistence/Repositories/Implement/AuditRepository.cs#L38

This might have been a problem for about 6 years it looks like.. 😅

We'd love some help getting this one fixed up!

@umbrabot
Copy link

Hi @kimschurmann,

We're writing to let you know that we would love some help with this issue. We feel that this issue is ideal to flag for a community member to work on it. Once flagged here, folk looking for issues to work on will know to look at yours. Of course, please feel free work on this yourself ;-). If there are any changes to this status, we'll be sure to let you know.

For more information about issues and states, have a look at this blog post

Thanks muchly, from your friendly Umbraco GitHub bot :-)

@kimschurmann
Copy link
Author

@nul800sebastiaan any small fix would be helpful here? Trim the text, try/catch it and log the error? Anything.. But an AuditLog that throws an exception is not a good option.

@nul800sebastiaan
Copy link
Member

Yeah any fix would work for me I guess, first of all it needs to be clear what is being inserted that is too long and then it can be fixed depending on what it is.

@kimschurmann
Copy link
Author

@nul800sebastiaan does it matter what is being inserted? If it fails if the length exceeds the size of the column in SQL then do that validation here? Should be a quick fix?

@SteveVaneeckhout
Copy link
Contributor

Something's not right. The truncated string is only 100 characters long, but the column is defined to have a max of 500 characters.

Can you check the length of the column in SQL Server?

@nul800sebastiaan
Copy link
Member

@nul800sebastiaan does it matter what is being inserted?

Yes, I want to know where we're trying to insert more than 500 chars, knowing that the table doesn't support that. Seems like we made a mistake if that's the case and then that needs to be fixed. 😃

The truncated string is only 100 characters long,

@SteveVaneeckhout which truncated string are you referring to? 🤔

@SteveVaneeckhout
Copy link
Contributor

@nul800sebastiaan It's on the first line of his stacktrace:

English (United Kingdom), English, Spanish (Spain), Estonian (Estonia), Finnish (Finland), French (B

@kevinstampe
Copy link

kevinstampe commented Jan 6, 2021

@nul800sebastiaan I've made a PoC on this locally with a fresh install.
Would it be viable to substring the parameter in the src\Umbraco.Core\Persistence\Dtos\LogDto.cs class? It fixes the issue, no idea if it could introduce other problems though.

    internal class LogDto
    {
        ...
        private string _parameters;
        ...
        [Column("parameters")]
        [NullSetting(NullSetting = NullSettings.Null)]
        [Length(500)]
        public string Parameters { get => _parameters.Length > 500 ? _parameters.Substring(0, 500) : _parameters; set => _parameters = value;
    }

@SteveVaneeckhout It is the stack trace generation, that is limiting the string to 100 characters. The actual string is over 500 characters.

@nul800sebastiaan
Copy link
Member

@SteveVaneeckhout Ah!! Good point, any idea @kimschurmann if your database schema is wrong here?

@kevinstampe Looks fine, but I'd rather figure out first if we need to do anything at all, I still don't know of anything that is trying to insert more than 500 chars and I'd like to understand first what is trying to be insterted and why. The second worst thing after failing an insert is only getting half the data you were trying to log. 😅

@kevinstampe
Copy link

kevinstampe commented Jan 6, 2021

In src\Umbraco.Core\Services\Implement\ContentService.cs line 809, the code actually puts the langs string into both the Message column (max length 4000) and the Parameters column (max length 500).

        public OperationResult Save(IContent content, int userId = Constants.Security.SuperUserId, bool raiseEvents = true)
        {
        ...
            if (culturesChanging != null)
            {
                var langs = string.Join(", ", _languageRepository.GetMany()
                    .Where(x => culturesChanging.InvariantContains(x.IsoCode))
                    .Select(x => x.CultureName));
                Audit(AuditType.SaveVariant, userId, content.Id, $"Saved languages: {langs}", langs); // <-- line 809, where the 'magic happens'
            }
            else
                Audit(AuditType.Save, userId, content.Id);
        ...
        }

@nul800sebastiaan Do we have any reason to fill the data in twice, in the same row?

The row it inserts, looks like this:
id | userId | NodeId | entityType | Datestamp | logHeader | logComment | parameters
3 | -1 | 1062 | Document | 06-01-2021 17:40 | SaveVariant | Saved languages: English (United States) | English (United States)

The reason it fails is because alot of countries are being saved at once, then the logger receives a string longer than 500 characters, generated by the 'langs' variable.
So this could actually happen, if you created enough language variants at once, without using the component @kimschurmann included.

EDIT:
I just tested this without the component, if i have enough languages in Umbraco to surpass total character length of 500 by combining all of the languages, and create a new piece of content, go through all of the variants and give them a name, i get the same error.

@kimschurmann
Copy link
Author

Exactly @kevinstampe - the problem is if you try to save too many language variations of a piece of content.

@kimschurmann
Copy link
Author

@nul800sebastiaan
The worst thing is breaking the user experience and functionality due to audit logging. The second worst is not stopping the bleeding (6 years) and creating a quick fix for this. Long down the list is getting a truncated audit log message imho :)

When it was decided that the column is only 500 chars - it was also decided that truncated audit logs was a possibility. I think most users are fine with that - but not being able to publish pages is not fine.

@nul800sebastiaan
Copy link
Member

.Wait, you can't publish pages now? That wasn't clear from your initial report, that changes things!

So.. add 20 languages and try to publish a page fails?

@nul800sebastiaan Do we have any reason to fill the data in twice, in the same row?

No that seems a little silly 😊

@kevinstampe
Copy link

@nul800sebastiaan Yeah, well.. If the pages you try to publish aren't saved first individually, then it fails. It is not the publishing that fails, it is the saving.

@kimschurmann
Copy link
Author

@nul800sebastiaan - sorry (I did not explicitly write that)- the exception is propagated to the client and shown to the user. The stacktrace above is taken from that error dialog. So no save event is executed. We can save them invidiually of course - but not more than what is 500 chars long :)

I think some wrapping with try/catch would be nice in these scenarios - no logging events should be able to break (core) functionality imo?

@nul800sebastiaan
Copy link
Member

No of course it shouldn't. We'll fix!

@nul800sebastiaan nul800sebastiaan added status/regression state/sprint-candidate We're trying to get this in a sprint at HQ in the next few weeks and removed community/up-for-grabs labels Jan 6, 2021
@kimschurmann
Copy link
Author

@nul800sebastiaan thanks - we are pondering on a dirty fix locally - as this might drag on a bit before it is available in a version? Do you have any suggestion on that? We are thinking of perhaps just altering the column to nvarchar(4000) or even MAX? Or creating and injecting a logger that handles this edge case and uses the base functionality for the rest?

@nul800sebastiaan
Copy link
Member

Yeah of course, just make it NVARCHAR(MAX) for now.

@kimschurmann
Copy link
Author

@nul800sebastiaan thanks - just worried you might change the schema too in a migration and that would fail if there are warnings/errors on possible truncated/lost data?

@nul800sebastiaan
Copy link
Member

I think that should be fine, we don't check if the column is exactly 500 chars / 4000 chars first.

@kimschurmann
Copy link
Author

@nul800sebastiaan but SQL does? :)

@nul800sebastiaan
Copy link
Member

🤷‍♂️ no idea, does it?

@nul800sebastiaan
Copy link
Member

ALTER TABLE table_name 
ALTER COLUMN column_name new_data_type(size);

I don't see why that would check what the old size was or how it would know that it needs to be an exact amount. 😊

@kevinstampe
Copy link

kevinstampe commented Jan 6, 2021

@nul800sebastiaan it wouldnt fail on any check, but if you decrease a columns data size to ex. 500 from 1000 in a migration, and you have data that is larger than 500, then the migration would fail

@nul800sebastiaan
Copy link
Member

Ah I see! Well, I don't know what we're going to do. But I'll update here when we do. Until then, there's a small risk we don't set it to max, for sure! 😅

@Albion87
Copy link

Any idea when do we see a fix for this issue?

@LottePitcher
Copy link
Contributor

LottePitcher commented Aug 26, 2021

We have just run into this issue as well.

Of course it's annoying to replicate manually as you need to update say 30+ variants on one node, then save/publish them all in one go. You could argue that people wouldn't be updating that many different variants without saving more frequently!

However we hit the problem because uSync was publishing a new piece of content with 71 variants to a different environment. So of course one node was being updated for 71 different languages in one go. And this error appears to be preventing uSync from properly creating all the variants. Perhaps Umbraco Deploy might have the same problem if people try pushing content with a large number of languages?

I have implemented the following workaround locally:

ALTER TABLE umbracoLog ALTER COLUMN [parameters] nvarchar(4000) NULL;

I then re-ran the uSync import and this time it all worked fine and all the content variants were created properly.

FYI when Umbraco logs the 'PublishVariant' activity as a result of this, the 'parameters' column contains:

English (United States), English (United Kingdom), Spanish (Spain), Amharic (Ethiopia), Bulgarian (Bulgaria), Czech (Czech Republic), Danish (Denmark), German (Germany), Greek (Greece), English (Australia), English (Belgium), English (Canada), English (Ghana), English (Ireland), English (India), English (Kenya), English (Nigeria), English (New Zealand), English (Singapore), English (South Africa), Spanish (Chile), Spanish (Colombia), Spanish (Mexico), Spanish (Peru), Spanish (United States), Spanish (Uruguay), Spanish (Bolivarian Republic of Venezuela), Finnish (Finland), French (Belgium), French (Canada), French (Cameroon), French (France), Hindi (India), Croatian (Croatia), Hungarian (Hungary), Indonesian (Indonesia), Italian (Italy), Japanese (Japan), Korean (Korea), Burmese (Myanmar), Dutch (Belgium), Dutch (Netherlands), Norwegian, Polish (Poland), Portuguese, Portuguese (Brazil), Romanian (Romania), Russian (Russia), Swedish (Sweden), Kiswahili (Kenya), Thai (Thailand), Ukrainian (Ukraine), Vietnamese (Vietnam), Chinese (Traditional, Hong Kong S.A.R.), Chinese (Traditional, Taiwan)

Those 71 variants have a character count of 1104.

If we implement this workaround on our production database, and then this column is changed in a future release to a smaller size it sounds like that migration would fail. Which is not ideal. But this is show stopper for us as it is preventing us from being able to push content to production, so not sure we have any choice. So maybe we should up it to 1500 which is big enough for our use case and just hope for the best?!

@nul800sebastiaan
Copy link
Member

Thanks for the update! Looks like we haven't been able to prioritize this issue.

At this point we'd love a pull request to fix this. We'd be looking for a migration that works on both SQLCE and SQL Server, it should take into account that people have already manually updated the column size, so it won't throw an error during the upgrade.

If anyone is up for the task then we'd love that! 👍

@nul800sebastiaan nul800sebastiaan added community/up-for-grabs and removed state/sprint-candidate We're trying to get this in a sprint at HQ in the next few weeks status/regression labels Aug 30, 2021
@umbrabot
Copy link

Closing this in relation to PR #11578 - make sure to read the close reason on #11578

@marwaldv marwaldv mentioned this issue Nov 21, 2023
1 task
@NijasHameed
Copy link

NijasHameed commented Jul 19, 2024

umbracoLog

@LottePitcher I am also facing this issue in my application aswell, I just upgraded my aplication from version 10 to 13, are these scripts not executing while the umbraco upgrade?

@NijasHameed
Copy link

NijasHameed commented Jul 19, 2024

https://github.com/umbraco/Umbraco-CMS/blob/v13/dev/src/Umbraco.Infrastructure/Persistence/Dtos/LogDto.cs

The max length still configured 500, it should be more than that, because I had around 50 language variants for my content 500 is not enough for that, is there any reason why its not changing to an higher limit character type?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants